Async/Await - Best Practices in Asynchronous Programming
https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
Figure 1 Summary of Asynchronous Programming Guidelines
Name | Description | Exceptions |
Avoid async void | Prefer async Task methods over async void methods | Event handlers |
Async all the way | Don’t mix blocking and async code | Console main method |
Configure context | Use ConfigureAwait(false) when you can | Methods that require context |
Avoid Async Void
You should prefer "async Task" to "async void". Async Task methods enable easier error-handling(propagate up or not), composability (Task.waitAll ...) and testability. The exception to this guideline is asynchronous event handlers, which must return void. This exception includes methods that are logically event handlers even if they’re not literally event handlers (for example, ICommand.Execute implementations).
Async All the Way
"Async all the way” means that you shouldn’t mix synchronous and asynchronous code without carefully considering the consequences. In particular, it’s usually a bad idea to block on async code by calling Task.Wait or Task.Result. This is an common problem for programmers who try to convert just a small part of their application and wrapping it in a synchronous API so the rest of the application is isolated from the changes. Unfortunately, this can cause deadlocks, in the case of GUI or ASP.NET (not if in a console application). The exception semantic for await and Task.Wait is also different, Exception versus AggregateException. So do not do this except in the Main method for console applications.
Figure 5 The “Async Way” of Doing Things
To Do This … | Instead of This … | Use This |
Retrieve the result of a background task | Task.Wait or Task.Result | await |
Wait for any task to complete | Task.WaitAny | await Task.WhenAny |
Retrieve the results of multiple tasks | Task.WaitAll | await Task.WhenAll |
Wait a period of time | Thread.Sleep | await Task.Delay |
Configure Context
Await require context, see the following code, if you swap the commented-out lines in DelayAsync, it will not deadlock,
public static class DeadlockDemo { private static async Task DelayAsync() { await Task.Delay(1000);
//await Task.Delay(1000).ConfigureAwait(continueOnCapturedContext: false);
} // This method causes a deadlock when called in a GUI or ASP.NET context.
public static void Test()
{ // Start the delay.
var delayTask = DelayAsync(); // Wait for the delay to complete.
delayTask.Wait();
}
}
This technique is particularly useful if you need to gradually convert an application from synchronous to asynchronous.
You should not use ConfigureAwait when you have code after the await in the method that needs the context.
posted on 2016-10-30 21:57 SuperSaiyan 阅读(310) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库