Skip to content

[HttpListener] HttpListener Start()/Stop()/Start()/BeginGetContext() causes ObjectDisposedException on Windows #30284

Description

@RobinsonWM

The code below always causes an exception on Windows. I am using .NET Core 2.2.

var l = new System.Net.HttpListener() { Prefixes = { "http://+/foo/" } };
l.Start();
l.BeginGetContext((f) => { }, null);
l.Stop();
l.Start();
l.BeginGetContext((f) => { }, null);
Message: System.ObjectDisposedException : Cannot access a disposed object.
Object name: 'System.Threading.ThreadPoolBoundHandle'.
  at System.Threading.ThreadPoolBoundHandle.EnsureNotDisposed()
  at System.Threading.ThreadPoolBoundHandle.AllocateNativeOverlapped(IOCompletionCallback callback, Object state, Object pinData)
  at System.Net.AsyncRequestContext.Allocate(ThreadPoolBoundHandle boundHandle, UInt32 size)
  at System.Net.ListenerAsyncResult..ctor(HttpListener listener, Object userState, AsyncCallback callback)
  at System.Net.HttpListener.BeginGetContext(AsyncCallback callback, Object state)

The documentation states that it is valid to call .Stop() followed by .Start(), so I don't believe we would expect this code to throw: https://docs.microsoft.com/en-us/dotnet/api/system.net.httplistener.stop?view=netcore-2.2#remarks

I noticed this problem when porting an application from .NET Framework 4.5 to .NET Core 2.2 (that is, the code above does not throw on .NET Framework.) The ThreadPoolBoundHandle appears to be handled quite differently in .NET Core, and this appears to be specific to Windows.

On Windows, _requestQueueBoundHandle is created lazily the first time it is accessed. Stop() calls CloseRequestQueueHandle() which disposes _requestQueueBoundHandle without setting it to null, and calling Start() does not recreate it. So the next call to BeginGetContext() ends up using a handle that was disposed.
https://github.com/dotnet/corefx/blob/master/src/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs#L453

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions