我目前正在一个超过2人的团队中开展一个项目。团队中的每个人都拥有不同程度的技能和知识,特别是异步/等待关键字,用于C#5中的异步编程。我个人已经对这个范例有了很多了解,并熟悉它的一些复杂性和难题,但有些团队没有。有没有人提出一个很好的约定,用于注释/归属代码,返回异步Task / async void,以指示是否必须等待调用的结果,或者是否可以让它运行" fire and forget&#34 ;在后台?该项目使用异步编程有很多(过度?)。我们目前正致力于提高性能,并且有很多实例,其中函数的结果是异步的任务,不等待并留下火灾/遗忘,并且async void结果应该是真正的等待的任务。我认为应该根据回报类型明确答案,但对团队中的每个人来说并不明显。
答案 0 :(得分:2)
有没有人提出一个很好的约定,用于注释/归属代码,返回异步Task / async void,以指示是否必须等待调用的结果,或者是否可以让它在“fire and forget”中运行背景?
async void
方法适用于与事件处理程序的兼容性。它们绝不是“在火中使用它而忘记场景”的指标。您只应在内部使用异步方法await
时使用它们,因为它们的异常处理机制与async Task
或async Task<T>
不同。我建议阅读Stephan Cleary的Best Practices in Asynchronous Programming,其中有一段关于使用async void的内容。
对于你的问题,我真的不是火的粉丝而忘记方法。如果你仍然想要使用它们,你应该让它们返回Task
并附加一个延续,它负责处理安全方面的错误处理。有点像:
public async Task FireAndForget()
{
await Task.Delay(1000);
Console.WriteLine("Foo")
}
public static void ForgetSafely(this Task task)
{
// Handle exceptions here.
}
并将其用作:
FireAndForget().ForgetSafely();
火灾和忘记不应该是您的代码库中的常见方法。如果是的话,你做错了什么。对于那些确实需要它们的情况,只需记录您的方法并声明可以以火灾和遗忘的方式使用,但应该正确处理异常。
要记住的另一件事是,当使用async Task
而不是async void
时,发出await
关键字会导致编译器生成错误,这会导致其他开发人员进入你的团队质疑他们对方法的使用:
警告CS4014:由于未等待此呼叫,因此在呼叫完成之前将继续执行当前方法。考虑将'await'运算符应用于调用的结果。
有关async void的更多探索: