CancellationTokenSource has been disposed #1549

Closed
victorcea87 opened this Issue Feb 19, 2013 · 16 comments

Projects

None yet

10 participants

@victorcea87

Hi,

I just upgrade to 1.0 my SignalR server and client, and now I have this error:

Exception information:
Exception type: ObjectDisposedException
Exception message: The CancellationTokenSource has been disposed.

Server stack trace:
at System.Threading.CancellationTokenSource.ThrowIfDisposed()
at System.Threading.CancellationTokenRegistration.Dispose()
at Microsoft.AspNet.SignalR.Infrastructure.CancellationTokenExtensions.<>c__DisplayClass61.<SafeRegister>b__1() at Microsoft.AspNet.SignalR.Infrastructure.DisposableAction.Dispose(Boolean disposing) at Microsoft.AspNet.SignalR.Infrastructure.DisposableAction.Dispose() at Microsoft.AspNet.SignalR.Transports.TransportHeartbeat.EndConnection(ConnectionMetadata metadata) at Microsoft.AspNet.SignalR.Transports.TransportHeartbeat.AddConnection(ITrackingConnection connection) at Microsoft.AspNet.SignalR.Transports.LongPollingTransport.ProcessRequest(ITransportConnection connection) at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(HostContext context) at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.ProcessRequest(HostContext context) at Microsoft.AspNet.SignalR.Owin.CallHandler.Invoke(IDictionary2 environment)
at Microsoft.AspNet.SignalR.Owin.Handlers.HubDispatcherHandler.Invoke(IDictionary`2 environment)
at Microsoft.Owin.Host.SystemWeb.OwinCallContext.Execute()
at Microsoft.Owin.Host.SystemWeb.OwinHttpHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object extraData)

It's a bug?

Thanks.

@davidfowl
Member

Nope that's by design, this exception is caught and handled appropriately:

https://github.com/SignalR/SignalR/blob/master/src/Microsoft.AspNet.SignalR.Core/Infrastructure/CancellationTokenExtensions.cs#L35

This can happen if the connection disconnects before we get a chance to setup anything.

You must be seeing a first chance exception. If you're seeing it more often than you used to then create a new project with repro steps we can follow to see this.

@MrOnosa
MrOnosa commented Feb 19, 2013

I am also getting this. It seems like every longpolling request ends with this exception. This only occurs on our load balanced servers, though. I will attempt to put together a repro if time permits.

@victorcea87

I don't know what happen but I don't see no error in server, only the error that I paste in the first post :(

I debug the server but I don't get any error :(

@victorcea87

You can repro this:

IIS 7
Windows Server 2008 R2
ASP.NET App Pool Framework 4
HTTPS Security with HostName
SignalR 1.0

Then, the problem can be repro if you try to connect to SignalR server using the negotiate url directly or also, I have a .NET SignalR Client with 1.0 version, I get to connect but each 2 seconds the clients event error is fired with 500 - internal server error.
My signalR .NET client connect using:

New HubConnection(url)
CreateHubProxy(HubName)
Connect
Join

Then I Connect ok but the error event is fired with error 500 in server.

Finally, in eventVwr or in fiddler you can see the error what I paste in the first post.

Note: Obviously, in previous versions it works fine.

@zahhak
zahhak commented Feb 20, 2013

Here is a sample project i've created that reproduces this issue.
https://github.com/zahhak/SignalRNet40CancellationTokenBug

I'm reproducing this only when the server that is running the web application has ONLY .NET 4.0 installed. If the server has .NET 4.5 installed the issue is not reproducible.
Validated on Windows 7 with .NET 4.0 and Windows Server 2008 R2 with .NET 4.0.

@abillingsley

👍 I am experiencing this too. We are using Windows Server 2008 R2 with .NET 4.0

@davidfowl davidfowl was assigned Feb 22, 2013
@davidfowl
Member

I'm running the sample and this is the output I see:

Received: 0
Reconnected
Received: 1
Received: 2
Reconnected
Received: 3
Received: 4
Reconnected

I guess it shouldn't be reconnecting.

@victorcea87

Exactly, that's the problem, and also in server is fired the 500 error.

@davidfowl
Member

Ok I have a fix. I'll change this to 1.0.1 since it's a regression caused in 1.0.

@davidfowl
Member

For those interested, here's why it only happens on 4.0:

4.0

public void Dispose()
{
    if (this.m_tokenSource != null)
    {
        this.m_tokenSource.ThrowIfDisposed();
    }
    bool flag = this.TryDeregister();
    if ((((this.m_tokenSource != null) && this.m_tokenSource.IsCancellationRequested) && (!this.m_tokenSource.IsCancellationCompleted && !flag)) && (this.m_tokenSource.ThreadIDExecutingCallbacks != Thread.CurrentThread.ManagedThreadId))
    {
        this.m_tokenSource.WaitForCallbackToComplete(this.m_callbackInfo);
    }
}

4.5

public void Dispose()
{
    bool flag = this.TryDeregister();
    CancellationCallbackInfo callbackInfo = this.m_callbackInfo;
    if (callbackInfo != null)
    {
        CancellationTokenSource cancellationTokenSource = callbackInfo.CancellationTokenSource;
        if ((cancellationTokenSource.IsCancellationRequested && !cancellationTokenSource.IsCancellationCompleted) && (!flag && (cancellationTokenSource.ThreadIDExecutingCallbacks != Thread.CurrentThread.ManagedThreadId)))
        {
            cancellationTokenSource.WaitForCallbackToComplete(this.m_callbackInfo);
        }
    }
}
@davidfowl davidfowl added a commit that referenced this issue Feb 22, 2013
@davidfowl davidfowl Fix issue on .NET 4.0 where response cancellation token is already di…
…sposed.

- Dispose the token only if it's not a result of ending an existing
  connection.
- Dispose the token before ending the connection.
- Catch ObjectDisposedException in SafeRegister's DisposableAction.

#1549
8e3c0e7
@RoyTinker

I'm using SignalR 1.0, .NET 4.0, and IIS 7.0, and I'm getting 100+ exception report emails every minute from Elmah:

System.ObjectDisposedException: The CancellationTokenSource has been disposed.

Server stack trace:
at System.Threading.CancellationTokenRegistration.Dispose()
at Microsoft.AspNet.SignalR.Infrastructure.DisposableAction.Dispose(Boolean disposing)
at Microsoft.AspNet.SignalR.Transports.TransportHeartbeat.AddConnection(ITrackingConnection connection)
at Microsoft.AspNet.SignalR.Transports.LongPollingTransport.ProcessRequest(ITransportConnection connection)
at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(HostContext context)
at Microsoft.AspNet.SignalR.Owin.CallHandler.Invoke(IDictionary2 environment) at Microsoft.AspNet.SignalR.Owin.Handlers.HubDispatcherHandler.Invoke(IDictionary2 environment)
at Microsoft.Owin.Host.SystemWeb.OwinCallContext.Execute()
at Microsoft.Owin.Host.SystemWeb.OwinHttpHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object extraData)

Exception rethrown at [0]:
at Microsoft.Owin.Host.SystemWeb.Utils.<>c__DisplayClass1.b__0(Exception ex)
at Microsoft.Owin.Host.SystemWeb.CallContextAsyncResult.End(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

@davidfowl davidfowl added a commit that referenced this issue Feb 22, 2013
@davidfowl davidfowl Fix issue on .NET 4.0 where response cancellation token is already di…
…sposed.

- Dispose the token only if it's not a result of ending an existing
  connection.
- Dispose the token before ending the connection.
- Catch ObjectDisposedException in SafeRegister's DisposableAction.

#1549
fdb4d28
@Xiaohongt
Contributor

verified

@Xiaohongt Xiaohongt closed this Feb 25, 2013
@demius
demius commented Feb 28, 2013

Hi David,

When will 1.0.1 be released on NuGet? I'm experiencing this exact problem and would prefer not to have to fork the repo.

@davidfowl
Member

The plan is to release it before EOW.

@x2764tech

I see this a lot with Chrome extension (uses longpolling for some reason), IIS 7, .Net 4.0 - initially I thought there was something badly wrong, but then I saw http://dev.chromium.org/throttling and understood that chrome itself blocks the requests after a certain number of failures, effectively causing signalR to fail.

@davidfowl
Member

@x2764tech it already been fixed in 1.0.1 which has been out on nuget for a few weeks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment