Hello,
following the reply here and according to the fact that JsonHttpClient should be thread safe we’ve refactored our web service proxy to use single, shared instance of JsonHttpClient.
Unfortunately we started to get some ObjectDisposedExceptions saying The CancellationTokenSource has been disposed.
further investigation resulted in:
-
single CancellationTokenSource is used for the lifetime of the
JsonHttpClient - it is being disposed when an exception is returned from http call
- SendAsync creates new instance of
CancellationTokenSourceit it is null, however …
… what we believe is happening is a rare case of race condition.
- request #1 is being fired, it uses the current instance of CTS
- request #2 is being initialized in parallel, using the current instance of CTS
- request #1 fails, current instance of CTS is being disposed
- request #2 initialization proceeds to the point where (.NET’s) HttpClient calls
CreateLinkedTokenSourceon the (already disposed) CTS
here’s the stack trace
System.ObjectDisposedException: The CancellationTokenSource has been disposed.
at System.Threading.CancellationTokenSource.ThrowObjectDisposedException()
at System.Threading.CancellationTokenSource.InternalRegister(Action`1 callback, Object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext)
at System.Threading.CancellationToken.Register(Action`1 callback, Object state, Boolean useSynchronizationContext, Boolean useExecutionContext)
at System.Threading.CancellationToken.InternalRegisterWithoutEC(Action`1 callback, Object state)
at System.Threading.CancellationTokenSource.CreateLinkedTokenSource(CancellationToken token1, CancellationToken token2)
at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at ServiceStack.JsonHttpClient.SendAsync[TResponse](String httpMethod, String absoluteUrl, Object request, CancellationToken token)
at ServiceStack.JsonHttpClient.PutAsync(IReturnVoid requestDto)
Please note the problem is very rare, it happens 2-3 times a day under a moderate/heavy traffic