浅谈C#中await运算符在不同类型应用中的不同行为

27 篇文章 1 订阅
9 篇文章 0 订阅

概要

C#中的await运算符,因其不会阻塞主线程,可以给用户更好的操作体验,所以广泛的应用于各种C#的应用中。

本文主要分析其在Console程序,Winform程序和WebApi程序中,其工作行为的异同点,来更好的使用该运算符。

基本概念

await运算符的基本功能是挂起当前的async方法,并直到异步方法完成,并返回。

基本实现

挂起async方法最简单的方式就是将该方法放到一个新的线程中。

下面我们看一下await在不同应用中的基本行为:

Console

private static async Task doAsyncWork(){
    await Task.Delay(2000);
    PrintTreadNumber();
}
public static async Task  Main(string[] args)
{
    PrintTreadNumber();
    await doAsyncWork();
    PrintTreadNumber();
 }

运行结果如下:

Current Thread Id is 1
Current Thread Id is 4
Current Thread Id is 4

从运行结果可以看出,await运算符的出现,让runtime启动了一个新的线程处理异步方法和异步方法后面的代码。

Winfrom

private static async Task doAsyncWork(){
    await Task.Delay(2000);
    PrintTreadNumber();
}
 private async void  btn_Click (Object sender, EventArgs e){
    PrintTreadNumber();
    await doAsyncWork();
    PrintTreadNumber();
 }

运行结果如下:

Current Thread Id is 1
Current Thread Id is 1
Current Thread Id is 1

从Winform的运行来看,一直是UI主线程在处理异步任务,runtime并没有为await后面的异步任务启动新的线程。

如果用ConfigureAwait方法强行启动子线程,代码如下:

private static async Task doAsyncWork(){
    await Task.Delay(2000);
    PrintTreadNumber();
}
private async void  btn_Click (Object sender, EventArgs e){
    PrintTreadNumber();
    await doAsyncWork();
    PrintTreadNumber();
}
private async Task doAsyncWork(){
    await Task.Delay(2000).ConfigureAwait(false);
    PrintTreadNumber();
}

运行结果如下:

Current Thread Id is 1
Current Thread Id is 5
Current Thread Id is 1

从运行结果可以看出,UI线程在调用doAsyncWork时候,当执行到 await Task.Delay(2000).ConfigureAwait(false),runtime启动了子线程完成异步运算, 因为调用了ConfigureAwait(false), 因此启动了新的线程,符合预期。

btn_Click 作为button的响应函数,考虑到里面可能有很多的UI操作,所以该响应函数直接与UI线程相关联。doAsyncWork后面并没有调用ConfigureAwait(false),代码等价于 await doAsyncWork().ConfigureAwait(true),表示后面的代码和await的代码共用一个线程,所以最后一个PrintTreadNumber打印线程号是1,即UI主线程的线程号。

WebApi

await运算符在WebApi和Console中的行为基本一致,由于没有UI线程的限制,所以runtime会启动一个子线程来处理await操作符修饰的异步代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值