C# Async与Await的使用

本文对比了使用 Thread 和 Async/Await 进行异步编程的方法,并通过示例代码展示了如何利用 C# 的 Async/Await 特性简化异步任务的编写过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 转自:http://www.cnblogs.com/mushroom/p/4575417.html

          http://www.cnblogs.com/zhili/archive/2013/05/15/Csharp5asyncandawait.html

这个是.NET 4.5的特性,所以要求最低.NET版本为4.5。

看很多朋友还是使用的Thread来使用异步多线程操作,基本上看不见有使用Async、Await进行异步编程的。各有所爱吧,其实都可以。只要正确使用就行,不过还是写了这篇文章推荐大家使用Async、Await。 原因就是:可以跟写同步方法一样去异步编程。代码则就非常的清晰,就跟写普通的代码一样,不用关系如何去异步编程,也让很多初级程序员也能够异步编程了。下面是一个使用Thread 多线程实现的异步例子,以及一个使用Async与Await的异步例子,接下来我们再简单理解下Async与Await的相关技术说明。

Thread多线程异步编程例子

  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         Console.WriteLine("主线程测试开始..");
  6.         Thread th = new Thread(ThMethod);
  7.         th.Start();
  8.         Thread.Sleep(1000);
  9.         Console.WriteLine("主线程测试结束..");
  10.         Console.ReadLine();
  11.     }
  12.  
  13.  
  14.     static void ThMethod()
  15.     {
  16.         Console.WriteLine("异步执行开始");
  17.         for (int i = 0; i < 5; i++)
  18.         {
  19.             Console.WriteLine("异步执行" + i.ToString() + "..");
  20.             Thread.Sleep(1000);
  21.         }
  22.         Console.WriteLine("异步执行完成");
  23.     }
  24. }

以上代码运行效果如下图

Async Await

 

使用Async与Await进行异步编程

  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         Console.WriteLine("主线程测试开始..");
  6.         AsyncMethod();
  7.         Thread.Sleep(1000);
  8.         Console.WriteLine("主线程测试结束..");
  9.         Console.ReadLine();
  10.     }
  11.  
  12.     static async void AsyncMethod()
  13.     {
  14.         Console.WriteLine("开始异步代码");
  15.         var result = await MyMethod();
  16.         Console.WriteLine("异步代码执行完毕");
  17.     }
  18.  
  19.     static async Task<int> MyMethod()
  20.     {
  21.         for (int i = 0; i < 5; i++)
  22.         {
  23.             Console.WriteLine("异步执行" + i.ToString() + "..");
  24.             await Task.Delay(1000); //模拟耗时操作
  25.         }
  26.         return 0;
  27.     }
  28. }

运行效果:

Async Await2

显而易见我们就跟写同步方法一样,完成了异步方法的编写,代码更清晰了。

只有拥有async才能在其内部使用await关键字。异步方法可以具有Task、Task<>或void的返回类型;

await关键字则是用于返回值是“可等待”类型(awaitable)的方法

转载于:https://www.cnblogs.com/chengjun/p/5366047.html

<think>好的,用户想要了解C#asyncawait关键字的使用示例,需要结合代码案例。首先,我得回忆一下相关的知识,确保自己理解正确。根据引用[4],async用来标记异步方法,await则用于等待异步操作完成,这样可以不阻塞主线程。 接下来,用户的问题是关于使用案例,所以需要提供具体的代码示例。引用[3]中有一个例子,展示了一个异步方法DoSomethingAsync,它返回Task,并在Task.Run中执行操作。然后在RunAsync方法中用foreach循环依次await每个任务。这可能是一个顺序执行的例子,但如果是并行的话,可能需要使用Task.WhenAll。 另外,引用[2]提到了几个常见的错误,比如死锁问题,当在UI线程调用.Wait()时可能导致死锁,这需要提醒用户注意使用ConfigureAwait(false)来避免。还有忘记await和过度使用async void的问题,这些也应该在注意事项中提到。 用户可能不仅需要基础示例,还可能想知道如何正确应用这些关键字,以及避免常见的陷阱。比如,在UI编程中,异步操作如何保持响应性,或者在Web API中处理并发请求。需要分不同场景给出例子。 然后,我需要组织这些信息,结构要清晰。先介绍asyncawait的基本用法,然后给出基础示例,比如异步下载数据或文件操作。接着,处理多个任务的情况,比如顺序执行和并行执行的区别。再提到常见的错误和解决方法,如死锁和忘记await。 还要确保代码格式正确,使用正确的语法。比如,异步方法返回Task或Task<T>,使用await调用。同时,注意在示例中展示正确的实践,比如在库代码中使用ConfigureAwait(false)来避免死锁。 可能还需要对比同步和异步方法的区别,让用户明白异步的优势。例如,在UI应用中,长时间操作不会冻结界面;在服务端提高吞吐量。 最后,总结使用时的注意事项,并生成相关问题,帮助用户进一步学习。比如,如何优化异步代码,或者在不同框架中的使用差异。</think>### C# async/await 使用示例解析 #### 一、基础用法 1. **异步方法定义** 使用 `async` 关键字修饰方法,并返回 `Task` 或 `Task<T>`。 ```csharp public async Task DownloadDataAsync(string url) { using HttpClient client = new HttpClient(); string result = await client.GetStringAsync(url); Console.WriteLine("下载完成"); } ``` 2. **await 等待异步操作** 在需要等待异步结果的语句前添加 `await`: ```csharp public async Task ProcessDataAsync() { await Task.Delay(1000); // 模拟耗时操作 Console.WriteLine("数据处理完成"); } ``` --- #### 二、多任务处理 1. **顺序执行任务** 通过 `await` 逐个执行异步操作: ```csharp public async Task RunSequentiallyAsync() { await DoTaskAsync(1); // 等待任务1完成 await DoTaskAsync(2); // 再执行任务2 } ``` 2. **并行执行任务** 使用 `Task.WhenAll` 实现并行执行: ```csharp public async Task RunParallelAsync() { Task task1 = DoTaskAsync(1); Task task2 = DoTaskAsync(2); await Task.WhenAll(task1, task2); // 同时等待所有任务完成 } ``` --- #### 三、实际场景案例 1. **UI 应用(避免界面冻结)** ```csharp private async void Button_Click(object sender, EventArgs e) { await Task.Run(() => { // 执行耗时计算(如图像处理) }); label.Text = "操作完成"; // 自动返回UI线程更新界面 } ``` 2. **Web API 异步处理请求** ```csharp public class DataController : ApiController { public async Task<IHttpActionResult> GetAsync() { var data = await FetchFromDatabaseAsync(); return Ok(data); } } ``` --- #### 四、常见错误解决 1. **死锁问题** 在同步上下文中直接调用 `.Wait()` 或 `.Result` 会导致死锁[^2]: ```csharp // 错误写法 public void CallAsyncMethod() { DeadlockDemoAsync().Wait(); // 阻塞主线程导致死锁 } // 正确解决:使用 ConfigureAwait(false) public async Task DeadlockDemoAsync() { await Task.Delay(1000).ConfigureAwait(false); } ``` 2. **忘记 await** 未使用 `await` 会导致异步操作未完成时继续执行后续代码: ```csharp public async Task ForgetAwaitDemoAsync() { DoSomethingAsync(); // 错误:未等待 Console.WriteLine("完成"); // 可能在异步操作前执行 } ``` --- #### 五、注意事项 1. **避免 `async void`** 仅在事件处理中使用 `async void`,其他场景应返回 `Task`。 2. **返回值处理** 异步方法返回值需用 `Task<T>` 包裹: ```csharp public async Task<int> CalculateAsync() { await Task.Delay(500); return 42; } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值