如何将C#旧版多任务代码改写为符合async/await规范的现代写法
改写后的完整代码
using System; using System.Threading; using System.Threading.Tasks; namespace TasksAsyncAwait { class Program { static async Task Main(string[] args) { using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; Task taskOne = RunTaskOneAsync(cancellationToken); Task taskTwo = RunTaskTwoAsync(cancellationToken); await Task.WhenAll(taskOne, taskTwo); Console.WriteLine("Program done."); } private static async Task RunTaskOneAsync(CancellationToken cancellationToken) { Console.WriteLine("Task 1 start"); for (int i = 0; i < 10; i++) { cancellationToken.ThrowIfCancellationRequested(); Console.WriteLine($"T1: {i}"); await Task.Delay(500, cancellationToken); } Console.WriteLine("Task 1 complete"); } private static async Task RunTaskTwoAsync(CancellationToken cancellationToken) { Console.WriteLine("Task 2 start"); for (int i = 0; i < 5; i++) { cancellationToken.ThrowIfCancellationRequested(); Console.WriteLine($"T2: {i}"); await Task.Delay(300, cancellationToken); } Console.WriteLine("Task 2 complete"); } } }
主要改动说明
- 将原来
Task.Factory.StartNew包裹的业务逻辑抽为独立的异步方法,方法名加Async后缀符合C#异步编码规范 - 用非阻塞的
await Task.Delay()替换原同步阻塞的cancellationToken.WaitHandle.WaitOne(),等待时不会占用线程空转,大幅提升资源利用率 - 用非阻塞的
await Task.WhenAll()替换原同步阻塞的Task.WaitAll(),避免主线程卡死 - 为
CancellationTokenSource添加using关键字,用完自动释放非托管资源,避免内存泄漏 - 所有异步操作都传递取消令牌,取消逻辑、执行效果和原代码完全一致
内容的提问来源于stack exchange,提问作者Nimral
相关产品推荐
相关产品推荐

