I'm implementing an interface with the async method Execute
. In this I need to call some synchronous code. (removing an item from a dictionary). What would be the best way to go about this?
Alternative 1.
internal class ClearClaimByClaimIdCache : IListenTo<ClaimStatusChangedEvent>
{
private readonly ICache<Guid, Claim> _cache;
public ClearClaimByClaimIdCache(ICacheFactory cacheFactory)
{
_cache = cacheFactory.GetOrCreateCache<Guid, Claim>("ClaimByClaimId");
}
public Task Execute(ClaimStatusChangedEvent @event)
{
_cache.Remove(@event.ClaimId);
return Task.CompletedTask;
}
}
Alternative 2.
public Task Execute(ClaimStatusChangedEvent @event)
{
return Task.Run(() => _cache.Remove(@event.ClaimId));
}
Alternative 3.
public async Task Execute(ClaimStatusChangedEvent @event)
{
await Task.Run(() => _cache.Remove(@event.ClaimId));
}
Or any better way?
1 Answer 1
If it's really just removing an item from a dictionary (and not e.g. doing synchronous file IO), then Alternative 1 is the best.
When you're using async for scalability (e.g. in ASP.NET), using Task.Run()
like this won't help you (since the number of threads used stays the same), it will only hurt you a bit (since Task.Run()
has some overhead).
When you're using async for responsiveness (e.g. in GUI applications), using Task.Run()
like this can make sense, but only for long-running operations (MS recommendation is operations that can take more than 50 ms). Since dictionary operations shouldn't take long you shouldn't use Task.Run()
here either.
await
does). If you were composing multiple actions inside of that method then I'd maybe say yes, use await, but otherwise just return the Task. \$\endgroup\$Task
-returning method is not the same as calling a callback synchronously. For example, theTask
method returns before the caller continues, so it won't have anything on the call stack. \$\endgroup\$