C# 死锁 TaskCompletionSource
在异步转同步时,使用不当容易造成死锁(程序卡死)
看如下案例:
有一个异步方法
private static async Task TestAsync()
{
Debug.WriteLine("异步任务start……");
await Task.Delay();
Debug.WriteLine("异步任务end……");
}
在执行如上异步方法时,尝试将其转换为同步方法
按照官方文档《使用任务简化异步编程》,TaskCompletionSource使用步骤:
- 获取var sourceTask =TaskCompletionSource.Task,
- 等待此sourceTask结果-sourceTask.Result
- 设置设置sourceTask.Result的结果值
private void TaskCompleteSourceDead_OnClick(object sender, RoutedEventArgs e)
{
AwaitByTaskCompleteSource(TestAsync());
Debug.WriteLine($"4. TaskCompleteSource_OnClick end");
}
private void AwaitByTaskCompleteSource(Task task)
{
var taskCompletionSource = new TaskCompletionSource<object>();
var taskFromSource = taskCompletionSource.Task;
task.ContinueWith(action =>
{
taskCompletionSource.SetResult(true);
});
var task1Result = taskFromSource.Result;
Debug.WriteLine($"3. AwaitByTaskCompleteSource end:{task1Result}");
}
但是,以上逻辑执行时,界面会卡死!卡死效果如下,卡死的时候点击界面其它按钮无任何反应。

为何会死锁?
猜测可能与Task.wait()类似的死锁,详细如下:
- UI线程调用子线程并等待子线程结果,
- 子线程执行过程中,切换到了UI线程(因为TestAsync是在UI线程运行的)
- 从而导致两个线程均处在阻塞状态(死锁)
关键字:死锁、TaskCompletionSource
参考资料:
C# 死锁 TaskCompletionSource的更多相关文章
- C# 异步转同步 TaskCompletionSource
本文通过TaskCompletionSource,实现异步转同步 首先有一个异步方法,如下异步任务延时2秒后,返回一个结果 private static async Task<string> ...
- C# 死锁 Task/AutoResetEvent
与之前<C# 死锁 TaskCompletionSource>类似,还有很多死锁的案例 使用Task异步转同步时,使用不当造成的死锁 private void Task_OnClick(o ...
- C# 同步转异步 TaskCompletionSource
当我们遇到一些异步执行又无法等待时的逻辑,比如动画的执行. 而业务上又需要等待逻辑的完成,再去处理后续的操作.这时需要转成异步方法 如下,同步执行一个动画后,再输出日志: private async ...
- C# 异步转同步
当我们的程序运行时,调用了一段异步的逻辑A,这段异步的逻辑无法转化为同步(如动画.下载进度等) 而,我们又需要等待异步逻辑A处理完成,然后再执行其它逻辑B. 那就迫切需要将异步转同步了! //参数bo ...
- C# 异步转同步 PushFrame
异步转同步-PushFrame 本文通过PushFrame,实现异步转同步 首先有一个异步方法,如下异步任务延时2秒后,返回一个结果 private static async Task<stri ...
- C# 同步转异步 AutoResetEvent
当我们的程序运行时,调用了一段异步的逻辑A,这段异步的逻辑无法转化为同步(如动画.下载进度等) 而,我们又需要等待异步逻辑A处理完成,然后再执行其它逻辑B. AutoResetEvent 同步转异步 ...
- C# 最基本的涉及模式(单例模式) C#种死锁:事务(进程 ID 112)与另一个进程被死锁在 锁 | 通信缓冲区 资源上,并且已被选作死锁牺牲品。请重新运行该事务,解决方案: C#关闭应用程序时如何关闭子线程 C#中 ThreadStart和ParameterizedThreadStart区别
C# 最基本的涉及模式(单例模式) //密封,保证不能继承 public sealed class Xiaohouye { //私有的构造函数,保证外部不能实例化 private ...
- 记一次 .NET 某电商无货源后端服务 死锁分析
一:背景 1. 讲故事 这个月初,星球里的一位朋友找到我,说他的程序出现了死锁,怀疑是自己的某些写法导致mongodb出现了如此尴尬的情况,截图如下: 说实话,看过这么多dump,还是第一次遇到真实的 ...
- 【C# Task】TaskCompletionSource
TaskCompletionSource具体功能 用于封装一个没有不带委托的任务实列.可以在其他线程控制该任务实列什么时候结束.取消.错误.类似于EventWaitHandle的功能. 属性 Task ...
随机推荐
- 3ds Max建模,Blend设计,VS2008控制WPF的3D模型例子
原文:3ds Max建模,Blend设计,VS2008控制WPF的3D模型例子 3ds Max建模,Blend设计,VS2008控制WPF的3D模型例子 所用的软件 3ds Max 9.0,Mic ...
- HDU4099-Revenge of Fibonacci(trie树+数学基础)
Revenge of Fibonacci Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 204800/204800 K (Java/ ...
- ehcache hibernate4整合问题
当在原有hibernate使用ehcache缓存的项目中加入ehcache时,报如下错误时 Caused by: org.hibernate.service.spi.ServiceException: ...
- C#引用CefSharp并屏蔽鼠标右键和禁止拖动放置事件
原文:C#引用CefSharp并屏蔽鼠标右键和禁止拖动放置事件 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u013564470/article/ ...
- 在微信浏览器里使用js或jquery实现页面重新刷新
function refresh() { var random = Math.floor((Math.random() * 10000) + 1); var url = decodeURI(windo ...
- windows下启动redis
解决方案 使用现成的基于windows的redis程序 github上有许多封装好的基于windows的redis程序,可以直接使用,但是版本更新不及时比如: https://github.com/M ...
- qt部分类释义
如果测试错误,输出包含源码的警告信息 Q_ASSERT Qtime最后一次star()或restar()到现在的毫秒数 QTime::elapsed QMetaObject::invokeMethod ...
- 查看window端口占用并结束相关进程
启动cmd命令行 运行netstat –ano,可列出所有端口情况 根据被占用的端口号,比如8081,运行netstat -aon|findstr "8081",找到它对应的PID ...
- 获取bing图片并自动设置为电脑桌面背景(使用 URLDownloadToFile API函数)
众所周知,bing搜索网站首页每日会更新一张图片,张张漂亮(额,也有一些不合我口味的),特别适合用来做电脑壁纸. 我们想要将bing网站背景图片设置为电脑桌面背景的通常做法是: 上网,搜索bing 找 ...
- generate eml file
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD ...