[C#学习笔记] - await/async 异步

概述

await/async 关键字组合是C#中异步实现的一种常用方式。

  • async用于修饰方法,表明该方法为异步方法。但只有async+await的组合才能真正实现异步的执行。若“异步方法”内没有await,则该方法不是异步方法,仍为同步模式。
  • 由于await只能用于异步方法中,所以方法必须用async修饰。
  • 异步方法的放回类型必须为voidTaskTask<TResult>中的一种。
  • 异步方法内必须含有await,用于表示异步等待的位置。虽然不太恰当,但有点类似debug中的断点。
  • await后只能修饰TaskTask<TResult>。(方法的返回类型或变量类型)
  • await task的内容等价于task.Result
  • await关键字上下的代码有可能处于不同的线程。

说的挺清楚,就是示例代码命名有点长有点绕。

https://www.cnblogs.com/zhaoshujie/p/11192036.html
https://www.cnblogs.com/zhili/archive/2013/05/15/Csharp5asyncandawait.html

死锁

public class AsyncDemo
{
    public async void Run()
    {
        Console.WriteLine($"Demo start\t{Thread.CurrentThread.ManagedThreadId}");
        var task = GetAsync();
        // await task; // 取消注释则无死锁
        string ret = task.Result; // 死锁位置A
        Console.WriteLine($"Demo end\t{Thread.CurrentThread.ManagedThreadId}");
    }

    public async Task<string> GetAsync()
    {
        Console.WriteLine($"GetAsync start\t{Thread.CurrentThread.ManagedThreadId}");
        var task = await Task.Run(() =>
        {
            Console.WriteLine($"Task start\t{Thread.CurrentThread.ManagedThreadId}");
            Thread.Sleep(2000);
            Console.WriteLine($"Task end\t{Thread.CurrentThread.ManagedThreadId}");
            return "xxxx";
        });// 死锁位置B
        Console.WriteLine($"GetAsync end\t{Thread.CurrentThread.ManagedThreadId}");

        return task;
    }
}

死锁状态

取消注释后
在这里插入图片描述

死锁的原因在于,两个死锁位置的代码均锁定了共享资源,即阻塞了当前的context。从线程id也可以看出,死锁的时候,GetAsync无法进入GetAsync end 1那一行,因为线程1正被阻塞在位置A。导致task的结果没办法返回线程1,处于等待中,形成了位置B。
注意,如果string ret = task.Result;代码不存在,即不使用task的结果,则两种情况都不会死锁。因为没有出现抢占共享资源的情况。

https://www.cnblogs.com/OpenCoder/p/4434574.html 死锁
https://blog.stephencleary.com/2012/02/async-and-await.html
https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值