首页 新闻 会员 周边 捐助

Task.WaitAll 线程阻塞导致主界面无法操作

0
悬赏园豆:200 [已解决问题] 解决于 2021-10-22 15:22

前提:winform程序,系统启动时,
var task1 = Task.Factory.StartNew(IOCRepository.RegisterServie, param);
var task2 = Task.Factory.StartNew(Logger.Init);
Task.WaitAll(task1, task2);
////消息提醒
//var task3 = Task.Factory.StartNew(PreLoadData);
//Task.WaitAll(task3);

PreLoadData方法如下,init是5秒请求数据库消息表是否有未读的消息
/// <summary>
/// 初始数据预加载
/// </summary>
private static void PreLoadData()
{
//消息提醒初始化
ThreadPool.QueueUserWorkItem(new WaitCallback(PopupLoader.Init));
}
调用上面消息提醒(后台服务插入消息提醒到数据库,PreLoadData方法5秒自动扫描数据库是否有新消息,然后右下角弹窗)

但是出现了诡异的问题,在主界面闲置几分钟后,就会卡住(不是无响应,右下角消息提醒会一直触发,主界面所有按钮等元素都无法点击(假死))

初步分析是因为Task.WaitAll线程阻塞,但是没想到有什么好的办法来解决,大家有什么好办法吗?
谢谢

何以解忧唯有撸码的主页 何以解忧唯有撸码 | 初学一级 | 园豆:37
提问于:2021-10-19 12:21
< >
分享
最佳答案
1

建议试试 await Task.WhenAll();

收获园豆:200
dudu | 高人七级 |园豆:31053 | 2021-10-19 14:32

谢谢园长,我试试,顺便请教下,这种情况具体原因是什么引起的? 出现情况不固定,有时候用着用着就卡了,没有无响应,但是界面假死,有时候空闲几分钟没用,就卡了.但是去掉消息提醒那几句,就不会卡

何以解忧唯有撸码 | 园豆:37 (初学一级) | 2021-10-19 15:33

@何以解忧唯有撸码: 原因就是Task.WaitAll造成的线程阻塞,可以看看我们的教训:一码阻塞,万码等待:ASP.NET Core 同步方法调用异步方法“死锁”的真相

dudu | 园豆:31053 (高人七级) | 2021-10-19 16:13
其他回答(2)
0

你这写法很怪异。
Task.StartNew了,然后里面ThreadPool,之后又task.Wait()
在线程池(空闲线程)够用的情况下,Task.StartNew和Task.Wait是多余的,跟直接ThreadPool无异。
在线程池不够用时,你这写法,会造成阻塞(假死)。甚至死锁。

pencile | 园豆:845 (小虾三级) | 2021-10-20 09:17
0

这个代码不死锁都不正常!好好了解下异步和多线程

realyrare | 园豆:214 (菜鸟二级) | 2021-12-07 11:00
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册