There are interface methods that you obviously know that will be async
, implementations that will read from the disk for example, you can easily decide to use Task
. There are also interface methods that might use async
, you can make them return Task
too.
I can’t help but see Task
as an implementation detail that I’m hesitant to put Task
on my interfaces when I’m not sure if the implementation will be async
/ will use async
methods. If I decide to not use Task
, the implementation methods can’t be async
when needed.
Although it feels weird to adjust the contract based on the requirement of the implementation, this is what I will do. Is this the correct way?
9
Is this the correct way?
Yes. Just use Task
if you know there will sometimes be opportunity to be asynchronous.
That still leaves you the opportunity to not, because the interface cannot require the use of async
– it can only require the return type of Task
or Task<T>
.
If you end up not needing to do anything asynchronously, you can use Task.FromResult()
to return a completed Task
with a value. For example:
protected override Task<int> SomeMethod() {
return Task.FromResult(1);
}
Or Task.CompletedTask
if there is no return value.
Otherwise, if you don’t specify Task
as the return type, and you want to do something asynchronously, you’re left with two options:
- Use synchronous methods in your implementation,
- If no synchronous methods are available for what you want to do (which is increasingly common), then you either have to:
- Block synchronously on the asynchronous methods, or
- Use
async void
(if the method returnsvoid
), which can cause other complications.
All of those are worse options than returning a completed Task
in cases where you don’t need to run asynchronously.
1