Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use Task in Interface Methods in C#?

Tags:

c#

async-await

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?

like image 939
dpp Avatar asked Nov 21 '19 15:11

dpp


People also ask

When should I use Task run C#?

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.

What is task in async and await?

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.

Is Task run blocking?

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.

Can I use async in interface?

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.


1 Answers

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:

  1. Use synchronous methods in your implementation,
  2. 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 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.

like image 122
Gabriel Luci Avatar answered Oct 01 '22 16:10

Gabriel Luci