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?
You can use Task. Run to move CPU-bound work to a background thread, but a background thread doesn't help with a process that's just waiting for results to become available. The async-based approach to asynchronous programming is preferable to existing approaches in almost every case.
The async keyword turns a method into an async method, which allows you to use the await keyword in its body. When the await keyword is applied, it suspends the calling method and yields control back to its caller until the awaited task is complete. await can only be used inside an async method.
Run is misused to run IO blocking tasks. Although the code will work just fine (e.g UI not not freeze) but it is still a wrong approach. This is because Task. Run will still block a thread from thread pool the entire time until it finishes the method.
Interfaces can't use async in a method declaration, simply because there is no need. If an interface requires that a method returns Task , the implementation may choose to use async , but whether it does or not is a choice for the implementing method.
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:
async void
(if the method returns void
), 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With