Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement interface method that returns Task<T>?

I have an interface

interface IFoo {   Task<Bar> CreateBarAsync(); } 

There are two methods to create Bar, one asynchronous and one synchronous. I want to provide an interface implementation for each of these two methods.

For the asynchronous method, the implementation could look like this:

class Foo1 : IFoo {   async Task<Bar> CreateBarAsync()   {     return await AsynchronousBarCreatorAsync();   } } 

But HOW should I implement the class Foo2 that uses the synchronous method to create Bar?

I could implement the method to run synchronously:

  async Task<Bar> CreateBarAsync()   {     return SynchronousBarCreator();   } 

The compiler will then warn against using async in the method signature:

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Or, I could implement the method to explicitly return Task<Bar>. In my opinion the code will then look less readable:

  Task<Bar> CreateBarAsync()   {     return Task.Run(() => SynchronousBarCreator());   } 

From a performance point of view, I suppose both approaches have about the same overhead, or?

Which approach should I choose; implement the async method synchronously or explicitly wrap the synchronous method call in a Task?

EDIT

The project I am working on is really a .NET 4 project with async / await extensions from the Microsoft Async NuGet package. On .NET 4, Task.Run can then be replaced with TaskEx.Run. I consciously used the .NET 4.5 method in the example above in the hope of making the primary question more clear.

like image 966
Anders Gustafsson Avatar asked Nov 05 '14 07:11

Anders Gustafsson


People also ask

How do I return a task object in C#?

The recommended return type of an asynchronous method in C# is Task. You should return Task<T> if you would like to write an asynchronous method that returns a value. If you would like to write an event handler, you can return void instead. Until C# 7.0 an asynchronous method could return Task, Task<T>, or void.

How do I return a task in async?

If you use a Task return type for an async method, a calling method can use an await operator to suspend the caller's completion until the called async method has finished. In the following example, the WaitAndApologizeAsync method doesn't contain a return statement, so the method returns a Task object.

How do I return a task without await?

C# Language Async-Await Returning a Task without awaitThere is only one asynchronous call inside the method. The asynchronous call is at the end of the method. Catching/handling exception that may happen within the Task is not necessary.

CAN interface have async 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.


1 Answers

When you have to implement an async method from an interface and your implementation is synchronous, you can either use Ned's solution:

public Task<Bar> CreateBarAsync() {     return Task.FromResult<Bar>(SynchronousBarCreator()); } 

With this solution, the method looks async but is synchronous.

Or the solution you proposed:

  Task<Bar> CreateBarAsync()   {     return Task.Run(() => SynchronousBarCreator());   } 

This way the method is truly async.

You don't have a generic solution that will match all cases of "How to implement interface method that returns Task". It depends on the context: is your implementation fast enough so invoking it on another thread is useless? How is this interface used a when is this method invoked (will it freeze the app)? Is it even possible to invoke your implementation in another thread?

like image 68
Guillaume Avatar answered Sep 20 '22 21:09

Guillaume