You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The EventLoopScheduler creates a SemaphoreSlim (referred to by its _evt field). By design, its Dispose method does not call _evt.Dispose directly. This is because the scheduler's designated thread might be using it. So that designated thread is responsible for calling Dispose on the _evt when it detects disposal.
The problem with this is that an EventLoopScheduler can be in a state where there is no thread currently running. There are two ways this can occur:
before the first work is scheduled
when being used via the derived NewThreadScheduler, the thread shuts down any time the scheduler goes idle (more generally this happens if ExitIfEmpty is true, but that internal property is currently set only by NewThreadScheduler
If Dispose is called when there is no current thread, the SemaphoreSlim is not disposed.
the SemaphoreSlim will be disposed. (It might not happen immediately, because it won't occur until the event loop thread detects disposal, but it generally happens eitehr during or very soon after Dispose.)
For the EventLoopScheduler, this is unlikely to cause problems in practice because it would be unusual to create one without then using it, and even then it would be fairly unusual to create a lot of them. So the impact is likely to be only that one SemaphoreSlim will be relying on finalization to perform any necessary cleanup.
It is more of an issue for the derived NewThreadScheduler, in which we expect to enter a "no thread" state every time the work queue is drained. It's the default state. Even then the impact is probably small because we don't expect large numbers of scheduler instances to be created. Nonetheless, this is a bug. The semaphore should be disposed of even when the scheduler has no current thread.
The text was updated successfully, but these errors were encountered:
Bug
Library version: 5.0
All platforms
The
EventLoopScheduler
creates aSemaphoreSlim
(referred to by its_evt
field). By design, itsDispose
method does not call_evt.Dispose
directly. This is because the scheduler's designated thread might be using it. So that designated thread is responsible for callingDispose
on the_evt
when it detects disposal.The problem with this is that an
EventLoopScheduler
can be in a state where there is no thread currently running. There are two ways this can occur:NewThreadScheduler
, the thread shuts down any time the scheduler goes idle (more generally this happens ifExitIfEmpty
is true, but that internal property is currently set only byNewThreadScheduler
If
Dispose
is called when there is no current thread, theSemaphoreSlim
is not disposed.If we run this code:
the
SemaphoreSlim
will be disposed. (It might not happen immediately, because it won't occur until the event loop thread detects disposal, but it generally happens eitehr during or very soon afterDispose
.)But if we remove the call to
Schedule
:the
SemaphoreSlim
will never be disposed.For the
EventLoopScheduler
, this is unlikely to cause problems in practice because it would be unusual to create one without then using it, and even then it would be fairly unusual to create a lot of them. So the impact is likely to be only that oneSemaphoreSlim
will be relying on finalization to perform any necessary cleanup.It is more of an issue for the derived
NewThreadScheduler
, in which we expect to enter a "no thread" state every time the work queue is drained. It's the default state. Even then the impact is probably small because we don't expect large numbers of scheduler instances to be created. Nonetheless, this is a bug. The semaphore should be disposed of even when the scheduler has no current thread.The text was updated successfully, but these errors were encountered: