前提: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线程阻塞,但是没想到有什么好的办法来解决,大家有什么好办法吗?
谢谢
建议试试 await Task.WhenAll();
谢谢园长,我试试,顺便请教下,这种情况具体原因是什么引起的? 出现情况不固定,有时候用着用着就卡了,没有无响应,但是界面假死,有时候空闲几分钟没用,就卡了.但是去掉消息提醒那几句,就不会卡
@何以解忧唯有撸码: 原因就是Task.WaitAll
造成的线程阻塞,可以看看我们的教训:一码阻塞,万码等待:ASP.NET Core 同步方法调用异步方法“死锁”的真相
你这写法很怪异。
Task.StartNew了,然后里面ThreadPool,之后又task.Wait()
在线程池(空闲线程)够用的情况下,Task.StartNew和Task.Wait是多余的,跟直接ThreadPool无异。
在线程池不够用时,你这写法,会造成阻塞(假死)。甚至死锁。
这个代码不死锁都不正常!好好了解下异步和多线程