Permalink
Browse files

Dispose of disconnect CancellationToken registrations on the .NET cli…

…ent.

Ensures old registrations belonging to old requests and responses get
disposed before creating new ones.
  • Loading branch information...
1 parent 32e83a6 commit fad9ed5ae58648bee566942d755437f69cd82d87 @halter73 halter73 committed Dec 5, 2012
@@ -118,6 +118,9 @@
<Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\DisposableAction.cs">
<Link>Infrastructure\DisposableAction.cs</Link>
</Compile>
+ <Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\Disposer.cs">
+ <Link>Infrastructure\Disposer.cs</Link>
+ </Compile>
<Compile Include="..\Microsoft.AspNet.SignalR.Client\Infrastructure\ErrorExtensions.cs">
<Link>Infrastructure\ErrorExtensions.cs</Link>
</Compile>
@@ -87,9 +87,6 @@
<Compile Include="..\Microsoft.AspNet.SignalR.Client\Transports\ServerSentEvents\SseEvent.cs">
<Link>Transports\ServerSentEvents\SseEvent.cs</Link>
</Compile>
- <Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\ExceptionsExtensions.cs">
- <Link>Infrastructure\ExceptionsExtensions.cs</Link>
- </Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
@@ -102,12 +99,18 @@
<Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\CancellationTokenExtensions.cs">
<Link>Infrastructure\CancellationTokenExtensions.cs</Link>
</Compile>
+ <Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\ExceptionsExtensions.cs">
+ <Link>Infrastructure\ExceptionsExtensions.cs</Link>
+ </Compile>
<Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\SafeCancellationTokenSource.cs">
<Link>Infrastructure\SafeCancellationTokenSource.cs</Link>
</Compile>
<Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\DisposableAction.cs">
<Link>Infrastructure\DisposableAction.cs</Link>
</Compile>
+ <Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\Disposer.cs">
+ <Link>Infrastructure\Disposer.cs</Link>
+ </Compile>
<Compile Include="..\Microsoft.AspNet.SignalR.Client\Connection.cs">
<Link>Connection.cs</Link>
</Compile>
@@ -71,6 +71,9 @@
<Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\DisposableAction.cs">
<Link>Infrastructure\DisposableAction.cs</Link>
</Compile>
+ <Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\Disposer.cs">
+ <Link>Infrastructure\Disposer.cs</Link>
+ </Compile>
<Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\SafeCancellationTokenSource.cs">
<Link>Infrastructure\SafeCancellationTokenSource.cs</Link>
</Compile>
@@ -97,6 +97,9 @@
<Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\DisposableAction.cs">
<Link>Infrastructure\DisposableAction.cs</Link>
</Compile>
+ <Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\Disposer.cs">
+ <Link>Infrastructure\Disposer.cs</Link>
+ </Compile>
<Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\SafeCancellationTokenSource.cs">
<Link>Infrastructure\SafeCancellationTokenSource.cs</Link>
</Compile>
@@ -121,6 +121,9 @@
<Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\DisposableAction.cs">
<Link>Infrastructure\DisposableAction.cs</Link>
</Compile>
+ <Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\Disposer.cs">
+ <Link>Infrastructure\Disposer.cs</Link>
+ </Compile>
<Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\SafeCancellationTokenSource.cs">
<Link>Infrastructure\SafeCancellationTokenSource.cs</Link>
</Compile>
@@ -54,6 +54,9 @@
<Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\DisposableAction.cs">
<Link>Infrastructure\DisposableAction.cs</Link>
</Compile>
+ <Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\Disposer.cs">
+ <Link>Infrastructure\Disposer.cs</Link>
+ </Compile>
<Compile Include="..\Microsoft.AspNet.SignalR.Core\Infrastructure\ExceptionsExtensions.cs">
<Link>Infrastructure\ExceptionsExtensions.cs</Link>
</Compile>
@@ -65,6 +65,7 @@ public LongPollingTransport(IHttpClient httpClient)
IRequest request = null;
var reconnectInvoker = new ThreadSafeInvoker();
var callbackInvoker = new ThreadSafeInvoker();
+ var requestDisposer = new Disposer();
if (connection.MessageId == null)
{
@@ -197,10 +198,11 @@ public LongPollingTransport(IHttpClient httpClient)
}
}
}
+ requestDisposer.Dispose();
}
});
- disconnectToken.SafeRegister(req =>
+ var requestCancellationRegistration = disconnectToken.SafeRegister(req =>
{
if (req != null)
{
@@ -221,6 +223,8 @@ public LongPollingTransport(IHttpClient httpClient)
}
}, request);
+ requestDisposer.Set(requestCancellationRegistration);
+
if (initializeCallback != null)
{
TaskAsyncHelper.Delay(ConnectDelay).Then(() =>
@@ -71,6 +71,7 @@ private void Reconnect(IConnection connection, string data, CancellationToken di
// If we're reconnecting add /connect to the url
bool reconnecting = initializeCallback == null;
var callbackInvoker = new ThreadSafeInvoker();
+ var requestDisposer = new Disposer();
var url = (reconnecting ? connection.Url : connection.Url + "connect") + GetReceiveQueryString(connection, data);
IRequest request = null;
@@ -106,6 +107,7 @@ private void Reconnect(IConnection connection, string data, CancellationToken di
Reconnect(connection, data, disconnectToken);
}
}
+ requestDisposer.Dispose();
}
else
{
@@ -115,7 +117,7 @@ private void Reconnect(IConnection connection, string data, CancellationToken di
var eventSource = new EventSourceStreamReader(stream);
bool retry = true;
- disconnectToken.SafeRegister(es =>
+ var esCancellationRegistration = disconnectToken.SafeRegister(es =>
{
retry = false;
es.Close();
@@ -185,13 +187,18 @@ private void Reconnect(IConnection connection, string data, CancellationToken di
};
// See http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.close.aspx
- eventSource.Disabled = response.Close;
+ eventSource.Disabled = () =>
+ {
+ requestDisposer.Dispose();
+ esCancellationRegistration.Dispose();
+ response.Close();
+ };
eventSource.Start();
}
});
- disconnectToken.SafeRegister(req =>
+ var requestCancellationRegistration = disconnectToken.SafeRegister(req =>
{
if (req != null)
{
@@ -211,6 +218,8 @@ private void Reconnect(IConnection connection, string data, CancellationToken di
}
}, request);
+ requestDisposer.Set(requestCancellationRegistration);
+
if (errorCallback != null)
{
TaskAsyncHelper.Delay(ConnectionTimeout).Then(() =>
@@ -34,8 +34,10 @@ public void Set(IDisposable disposable)
}
else
{
+#if !NET35 && !SILVERLIGHT && !NETFX_CORE
// Set has been called multiple times, fail
Debug.Fail("Multiple calls to Disposer.Set(IDisposable) without calling Disposer.Dispose()");
+#endif
}
}

0 comments on commit fad9ed5

Please sign in to comment.