C# 我应该避免“async void”事件处理程序吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19415646/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Should I avoid 'async void' event handlers?
提问by avo
I know it is considered generally a bad idea to use fire-and-forget async void
methods to start tasks, because there is no track of the pending task and it is tricky to handle exceptions which might be thrown inside such a method.
我知道使用即发即弃的async void
方法来启动任务通常被认为是一个坏主意,因为没有挂起任务的跟踪,并且处理可能在这种方法中抛出的异常很棘手。
Should I generally avoid async void
event handlers, as well?For example,
我通常也应该避免使用async void
事件处理程序吗?例如,
private async void Form_Load(object sender, System.EventArgs e)
{
await Task.Delay(2000); // do async work
// ...
}
I can rewrite it like this:
我可以像这样重写它:
Task onFormLoadTask = null; // track the task, can implement cancellation
private void Form_Load(object sender, System.EventArgs e)
{
this.onFormLoadTask = OnFormLoadTaskAsync(sender, e);
}
private async Task OnFormLoadTaskAsync(object sender, System.EventArgs e)
{
await Task.Delay(2000); // do async work
// ...
}
What are the underwater rocks for async event handlers, besides possible re-entrancy?
除了可能的重入之外,异步事件处理程序的水下岩石是什么?
采纳答案by Stephen Cleary
The guideline is to avoid async void
exceptwhen used in an event handler, so using async void
in an event handler is OK.
准则是避免在事件处理程序中使用时async void
除外,因此async void
在事件处理程序中使用是可以的。
That said, for unit testingreasons I often like to factor out the logic of all async void
methods. E.g.,
也就是说,出于单元测试的原因,我经常喜欢将所有async void
方法的逻辑分解出来。例如,
public async Task OnFormLoadAsync(object sender, EventArgs e)
{
await Task.Delay(2000);
...
}
private async void Form_Load(object sender, EventArgs e)
{
await OnFormLoadAsync(sender, e);
}
回答by Eric Lippert
Should I generally avoid async void event handlers, as well?
我通常也应该避免使用 async void 事件处理程序吗?
Generally event handlers are the one case where a void async method is not a potential code smell.
通常,事件处理程序是一种无效异步方法不是潜在代码异味的情况。
Now, if you do need to track the task for some reason then the technique you describe is perfectly reasonable.
现在,如果您出于某种原因确实需要跟踪任务,那么您描述的技术是完全合理的。
回答by Idrees Khan
Yes, generally async void of event handlers is the only case. If you want to know more about it you can check out a great video here at channel 9 The only case where this kind of fire-and-forget is appropriate is in top-level event-handlers. Every other async method in your code should return "async Task".
是的,通常 async void of event handlers 是唯一的情况。如果您想了解更多信息,可以在第 9 频道观看精彩视频The only case where this kind of fire-and-forget is appropriate is in top-level event-handlers. Every other async method in your code should return "async Task".
here is the link
这是链接
回答by Alexander Zwitbaum
If you use ReSharper, a free ReCommended Extensioncould be helpful for you. It analyzes the "async void" methods and highlights when used inappropriately. The extension can distinguish different usages of async void and provide appropriated quick fixes described here: ReCommended-Extension wiki.
如果您使用 ReSharper,免费的ReCommended Extension可能对您有所帮助。它分析“异步无效”方法并在使用不当时突出显示。该扩展可以区分异步无效的不同用法,并提供此处描述的适当的快速修复:ReCommended-Extension wiki。