WPF中10个线程无法同时启动的问题解决咨询
解决WPF中Task启动延迟的问题
首先得搞清楚为什么会出现前4个任务同时启动、后面的却延迟很久的情况——这其实和.NET的ThreadPool调度机制有关。默认情况下,Task.Factory.StartNew会使用线程池线程,而线程池有个最小工作线程数的设置(默认通常等于你的CPU核心数,比如4核就默认4个)。当你提交的任务数超过这个最小值时,线程池不会立刻创建新线程,而是会先等待一段时间,看看已有线程是否会释放,只有等不到的时候才会缓慢增加新线程,这就导致了后面的任务排队延迟。
再加上你的DoSomeWork应该是个长时间运行的操作(不然不会延迟这么久),线程池里的初始4个线程一直被占用,所以后面的任务只能等线程池慢慢扩容,自然就出现了5-10秒的延迟。
下面给你几个可行的解决方案:
方案1:使用TaskCreationOptions.LongRunning
告诉TaskFactory这个任务是长时间运行的,它会直接创建一个独立的非线程池线程,这样就不会占用线程池的配额,所有任务可以同时启动。修改后的代码如下:
private void DoParallel() { for (int i = 0; i < 10; i++) { Task.Factory.StartNew(() => { Console.WriteLine(DateTime.Now.ToString()); DoSomeWork(); }, TaskCreationOptions.LongRunning); // 加上这个参数 } }
方案2:调整ThreadPool的最小线程数
如果你还是想使用线程池线程,可以手动设置线程池的最小工作线程数,让它一开始就能容纳10个任务。在启动任务前加上这段代码:
// 设置最小工作线程数为10,IO线程数可按需调整 ThreadPool.SetMinThreads(10, 10); private void DoParallel() { for (int i = 0; i < 10; i++) { Task.Factory.StartNew(() => { Console.WriteLine(DateTime.Now.ToString()); DoSomeWork(); }); } }
注意:这个设置是全局的,会影响整个应用的线程池行为,所以如果你的应用还有其他依赖线程池的操作,要谨慎调整。
方案3:使用Task.Run结合LongRunning(可选)
如果你更习惯用Task.Run,也可以通过重载参数实现同样的效果,本质和方案1一致:
private void DoParallel() { for (int i = 0; i < 10; i++) { Task.Run(() => { Console.WriteLine(DateTime.Now.ToString()); DoSomeWork(); }, TaskCreationOptions.LongRunning); } }
测试验证
你可以运行修改后的代码,观察输出的时间戳,应该会看到10个任务的启动时间几乎一致,不会再出现明显的延迟。
内容的提问来源于stack exchange,提问作者Erhan Urun
相关产品推荐
相关产品推荐

