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
CancellationTokenSource
it 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
CreateLinkedTokenSource
on 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