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.
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.
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.
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.
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.
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?
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