Last active
November 8, 2019 15:57
-
-
Save azborgonovo/4db9c3f378a2e161add1f503dc471d44 to your computer and use it in GitHub Desktop.
Async WCF Operation Cancellation Pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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