Skip to content

Internal exception surfacing when calling Post on disposed MailBoxProcessor #17849

@majocha

Description

@majocha
Message: 
System.ObjectDisposedException : Cannot access a disposed object.
Object name: 'Microsoft.Win32.SafeHandles.SafeWaitHandle'.

  Stack Trace: 
SafeHandle.DangerousAddRef(Boolean& success)
Kernel32.SetEvent(SafeWaitHandle handle)
EventWaitHandle.Set()
Mailbox`1.Post(TMsg msg) line 193
FSharpMailboxProcessor`1.Post(TMsg message) line 419

I can see the above exception occasionally in this test:

member this.``After dispose is called, mailbox should stop receiving and processing messages``() = task {

I assume the expected behavior here is no exception?

I'll try to come up with consistent minimal repro, but the problem seems to be here:

match pulse with
| null -> () // no one waiting, leaving the message in the queue is sufficient
| ev ->
// someone is waiting on the wait handle
ev.Set() |> ignore

ev is disposed and Set will fail.

The fix seems to be to also assign null to pulse when disposing it here:

interface System.IDisposable with
member _.Dispose() =
lock syncRoot (fun () ->
if isNotNull inboxStore then
inboxStore.Clear()
arrivals.Clear()
isDisposed <- true)
if isNotNull pulse then
(pulse :> IDisposable).Dispose()

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-Diagnosticsmistakes and possible improvements to diagnosticsBugImpact-Low(Internal MS Team use only) Describes an issue with limited impact on existing code.

    Type

    No fields configured for Bug.

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions