Skip to content

Instantly share code, notes, and snippets.

@azborgonovo
Last active November 8, 2019 15:57
Show Gist options
  • Save azborgonovo/4db9c3f378a2e161add1f503dc471d44 to your computer and use it in GitHub Desktop.
Save azborgonovo/4db9c3f378a2e161add1f503dc471d44 to your computer and use it in GitHub Desktop.
Async WCF Operation Cancellation Pattern
[ServiceContract]
public interface IMyService
{
[OperationContract]
Task DoExpensiveOperation(Guid requestId);
[OperationContract(IsOneWay=true)]
void CancelExpensiveOperation(Guid requestId);
}
public class MyService : IMyService
{
private readonly ConcurrentDictionary<Guid, CancellationTokenSource> _requests = new ConcurrentDictionary<Guid, CancellationTokenSource>();
public Task DoExpensiveOperation(Guid requestId)
{
var cancellationTokenSource = _requests.AddOrUpdate(requestId, u => new CancellationTokenSource(), (u, source) => source);
try
{
// TODO: await call to async method sending over the cancellationTokenSource.Token
}
finally
{
_requests.TryRemove(requestId, out _);
}
}
public void CancelExpensiveOperation(Guid requestId)
{
if (_requests.TryRemove(requestId, out var cancellationTokenSource))
{
cancellationTokenSource.Cancel();
}
}
}
public class MyServiceClientProxy
{
private readonly MyServiceClient _myServiceClient;
public MyServiceClientProxy(MyServiceClient myServiceClient)
{
_myServiceClient = myServiceClient;
}
public Task DoExpensiveOperation(CancellationToken cancellationToken)
{
var requestId = Guid.New();
cancellationToken.Register(() => _myServiceClient.CancelExpensiveOperation(requestId));
return _myServiceClient.DoExpensiveOperation(requestId);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment