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 ...
随机推荐
- EPPlus简单使用
在使用之前需要在项目中添加对EEPULS.dll的引用 1,创建excel 2,创建sheet 3,添加内容 4,修改 5,保存 FileInfo newFile = new FileInfo(fil ...
- Android发展_备份短信
短信备份的原理 短信备份的原理.是用内容提供者读取短信,然后保存. public class SmsBackupUtils { // 回调接口 public interface SmsBacku ...
- WPF无边框实现拖动效果
这是在做弹幕的时候遇到的一个需求 透明背景,拖动弹幕=.= private void Window_MouseLeftButtonDown(object sender, MouseButtonEven ...
- Html 空格与换行
空格 换行 <br/> 调行距 <div style="line-height:10px"></div>
- layerui
引用layer.js,官网:http://layer.layui.com/常用属性:btn/icon/skin/time/content/yes(点击确认.提交) 常用窗体.alert layer.a ...
- IOS开发之delegate和Notification的区别
delegate针对one-to-one关系,并且reciever可以返回值给sender: notification 可以针对one-to-one/many/none,reciever无法返回值给s ...
- Genymotion常见问题解决方案
最近更新了Genymotion之后, 出了一大堆问题, 花了差不多两天的时间, 把一系列问题基本遇到遍了, 终于修成正果, 分享出来希望可以让大家少走一点弯路. 无法启动Genymotion;关键字: ...
- 图像滤镜艺术---(Lightleaks Filter)漏光滤镜
原文:图像滤镜艺术---(Lightleaks Filter)漏光滤镜 (Lightleaks Filter)漏光滤镜 漏光拍摄其实就是一种摄影手法,最初是因为强烈光照导致相片交卷的过分曝光,最终在成 ...
- 零元学Expression Blend 4 - Chapter 4元件重复运用的观念
原文:零元学Expression Blend 4 - Chapter 4元件重复运用的观念 本章将教大家Blend元件重复运用的观念,这在Silverlight设计中是非常重要的,另外加码赠送渐层工具 ...
- delphi7 xml通用解析转换为stringgrid
对于有n多记录的xml,可以填充到stringgrid中 其中 vkeynode 为 xml中 重复节点 function CommonAnalyzeXml(vxml,vkeynode: string ...