C# 死锁 TaskCompletionSource

在异步转同步时,使用不当容易造成死锁(程序卡死)

看如下案例:

有一个异步方法

1     private static async Task TestAsync()
2     {
3         Debug.WriteLine("异步任务start……");
4         await Task.Delay(2000);
5         Debug.WriteLine("异步任务end……");
6     }

在执行如上异步方法时,尝试将其转换为同步方法

按照官方文档《使用任务简化异步编程》,TaskCompletionSource使用步骤:

  1. 获取var sourceTask =TaskCompletionSource.Task,
  2. 等待此sourceTask结果-sourceTask.Result
  3. 设置设置sourceTask.Result的结果值
 1     private void TaskCompleteSourceDead_OnClick(object sender, RoutedEventArgs e)
 2     {
 3         AwaitByTaskCompleteSource(TestAsync());
 4         Debug.WriteLine($"4. TaskCompleteSource_OnClick end");
 5     }
 6     private void AwaitByTaskCompleteSource(Task task)
 7     {
 8         var taskCompletionSource = new TaskCompletionSource<object>();
 9         var taskFromSource = taskCompletionSource.Task;
10         task.ContinueWith(action =>
11         {
12             taskCompletionSource.SetResult(true);
13         });
14         var task1Result = taskFromSource.Result;
15         Debug.WriteLine($"3. AwaitByTaskCompleteSource end:{task1Result}");
16     }

但是,以上逻辑执行时,界面会卡死!卡死效果如下,卡死的时候点击界面其它按钮无任何反应。

为何会死锁?

猜测可能与Task.wait()类似的死锁,详细如下:

  1. UI线程调用子线程并等待子线程结果,
  2. 子线程执行过程中,切换到了UI线程(因为TestAsync是在UI线程运行的)
  3. 从而导致两个线程均处在阻塞状态(死锁)

 

关键字:死锁、TaskCompletionSource

 

参考资料:

同步转异步
异步转同步
死锁

转载于:https://www.cnblogs.com/kybs0/p/11143943.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值