用同步代码实现异步接口

时间:2019-06-21 21:06:49

标签: c# asynchronous

我有一组简单的代码,试图在其中实现带有异步方法的接口。到目前为止,所有实现都是利用其异步部分并最终等待的事情。但是,此接口的新实现是一个简单的同步操作-无需等待。

当我实现它时,首先感觉很奇怪。其次,Visual Studio通过警告来告诉我该方法将同步运行,这使我感到不舒服,这是我所期望的,但是警告告诉我,它对VS也很不利。我应该遵循更好的模式吗?

public interface IActivity
{
    async Task<bool> DoStuff();
}

//...

List<IActivity> activities = new List<IActivity>(){
   new SynchronousActivityA(),
   new SynchronousActivityB(),
   new AsynchronousActivityC()
};

foreach (var activity in activities){
    bool stuff = await activity.DoStuff();
    //do things with stuff.
}

我可以让DoStuff()实现做到这样:

await Task.Run(() => DoStuffSynchronously());

这将使我的警告消失,并感到“更正确”,但是我不确定这比仅仅编写DoStuff()实现(好像它是一个同步签名)会有什么好处。

1 个答案:

答案 0 :(得分:2)

  

具有异步方法的接口

从技术上讲,“一种返回Task<T>的方法”。 asyncawait是实施细节。

返回等待状态的方法是可能是异步的方法。同步返回完成的任务是完全可以接受的。

一种实现方法是使用Task.FromResult,但您还需要确保捕获异常并在任务中返回它们:

try { return Task.FromResult(DoStuffSynchronously()); }
catch (Exception ex) { return Task.FromException<bool>(ex); }

这有点罗word。它与没有async的{​​{1}}基本上具有相同的作用,但是您需要await删除警告消息,这也很尴尬。如果您经常这样做,则可能需要为其定义实用程序方法,例如在我的TaskHelper.ExecuteAsTask中使用AsyncEx library

您不应仅使用#pragma来“使代码异步”。 Task.Run使用线程池线程,在这种情况下是不必要的。