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 ...
随机推荐
- Java高级应用(一个)-文件夹监控服务
最近.在研究一些比较成熟的框架.他们还发现,他们中的一些相当不错的文章.现在,对于一些在你们中间一个简单的翻译(版的英文文章,非常有帮助). 译:原文链接 你有没有发现,当你编辑一个文件.同一时候使用 ...
- Codeforces Round #160 (Div. 2)---A. Roma and Lucky Numbers
Roma and Lucky Numbers time limit per test 1 second memory limit per test 256 megabytes input standa ...
- WPF范围选择控件(RangeSelector)
原文:WPF范围选择控件(RangeSelector) 版权声明:本文为博主原创文章,转载请注明作者和出处 https://blog.csdn.net/ZZZWWWPPP11199988899/art ...
- ehcache hibernate4整合问题
当在原有hibernate使用ehcache缓存的项目中加入ehcache时,报如下错误时 Caused by: org.hibernate.service.spi.ServiceException: ...
- Ubuntu更改 resolv.conf 重启失效
更改Ubuntu的 resolv.conf的时候,重启的时候,经常又给重置了.google大法找到方法. sudo apt-get install resolvconf 原来Ubuntu的resol ...
- Kubernetes使用集群联邦实现多集群管理
Kubernetes在1.3版本之后,增加了“集群联邦”Federation的功能.这个功能使企业能够快速有效的.低成本的跨区跨域.甚至在不同的云平台上运行集群.这个功能可以按照地理位置创建一个复制机 ...
- 反编译 war 包成传统项目的方法
需求 项目老大让外包做了官网,不甚满意,想自己搞搞,遂叫我反编译他们发过来的 war 包. 方法 第一步:解压 war 包其实就是 zip 压缩包,用 zip 解压. 第二步:反编译 查看 war 包 ...
- QTextStream 居然接受FILE*这样的传统参数
实在是太爽.太牛了,无话可说-
- iOS 监听控件某个属性的改变observeValueForKeyPath
创建一个测试的UIButton #import "ViewController.h" @interface ViewController () @property(nonatomi ...
- GIS基础软件及操作(五)
原文 GIS基础软件及操作(五) 练习五.空间分析的基本操作 空间分析的基本操作 空间分析模块 空间分析是基于地理对象的位置和形态的空间数据的分析技术,其目的在于提取和传输空间信息.空间分析是地理信息 ...