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

 

参考资料:

同步转异步
异步转同步
死锁
posted @   唐宋元明清2188  阅读(1996)  评论(1编辑  收藏  举报
编辑推荐:
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
点击右上角即可分享
微信分享提示
哥伦布
01:11发布
哥伦布
01:11发布
8°
西北风
2级
空气质量
相对湿度
81%
今天
中雨
3°/15°
周四
大雨
2°/14°
周五
小雨
4°/10°