欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# 死锁 TaskCompletionSource

程序员文章站 2023-11-06 10:25:52
在异步转同步时,使用不当容易造成死锁(程序卡死) 看如下案例: 有一个异步方法 在执行如上异步方法时,尝试将其转换为同步方法 按照官方文档《使用任务简化异步编程》,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     }

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

C# 死锁 TaskCompletionSource

为何会死锁?

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

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

 

关键字:死锁、taskcompletionsource