Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
242 views
in Technique[技术] by (71.8m points)

c# - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...