C# .NET线程池-无响应的WinForms UI 脚本

C# .NET线程池-无响应的WinForms UI 脚本,c#,winforms,backgroundworker,threadpool,C#,Winforms,Backgroundworker,Threadpool,我有一个Windows窗体应用程序。在主窗体内部有一个循环,循环大约3000次,在一个新线程上创建一个类的新实例来执行一些计算。请记住,此设置使用线程池,当只有大约100个循环的100个资产需要处理时,UI会保持响应。但一旦这个数字开始大幅增加,UI就会锁定到eggtimer模式,因此写入表单上列表框的日志就变得无法读取 问题 我认为最好的解决方法是使用后台工作人员,对吗? UI被锁定是因为即使我使用了很多不同的线程来提高速度,UI本身也不是独立的线程吗 非常感谢建议的实现 编辑 因此,让我们假

我有一个Windows窗体应用程序。在主窗体内部有一个循环,循环大约3000次,在一个新线程上创建一个类的新实例来执行一些计算。请记住,此设置使用线程池,当只有大约100个循环的100个资产需要处理时,UI会保持响应。但一旦这个数字开始大幅增加,UI就会锁定到eggtimer模式,因此写入表单上列表框的日志就变得无法读取

问题 我认为最好的解决方法是使用后台工作人员,对吗? UI被锁定是因为即使我使用了很多不同的线程来提高速度,UI本身也不是独立的线程吗

非常感谢建议的实现

编辑
因此,让我们假设,我不只是启动并排队处理3000个资产,而是决定分批处理100个资产。我将如何有效地进行这项工作?我之前曾尝试添加Thread.Sleep5000;在每一批100个线程被触发后,整个过程似乎都会失败……

更多的线程并不等于最高速度。事实上,线程太多等于速度变慢。如果您的任务只是与CPU相关,那么您应该只使用与内核数量相同的线程,否则您就是在浪费资源

在3000次迭代中,表单线程每次都试图创建一个线程。可能发生的情况是,线程池已达到最大值,表单处于挂起状态,因为它需要等待前一个线程完成,然后才能分配新线程


显然ThreadPool不是这样工作的。我以前从未用线程检查过它,所以我不确定。另一种可能性是,任务开始向UI线程注入调用,此时它将在GUI上放弃。

如果不看到代码,很难判断——但是,根据您所描述的,有一个疑点

您提到您现在已经在线程池上运行了它。切换到BackgroundWorker不会显著改变任何事情,因为它还使用线程池来执行。BackgroundWorker只是简化了调用

话虽如此,我怀疑问题在于你的通知返回到你的列表框的UI线程。如果调用过于频繁,用户界面可能会在试图跟上时变得无响应。如果您通过Control.Invoke将太多的状态信息反馈给UI线程,则可能会发生这种情况


否则,请确保您的所有工作都在线程池上完成,并且您没有阻塞UI线程,并且它应该可以工作。

如果您要创建3000个单独的线程,则您正在推送ThreadPool类的一部分:

如果应用程序受到突发事件的影响 大量的 线程池任务已排队,请使用 SetMinThreads方法来增加 空闲线程的最小数量。 否则,内置的延迟 创建新的空闲线程可能会导致 瓶颈

有关针对您的情况配置线程池的建议,请参阅MSDN主题

如果您的工作是CPU密集型的,那么拥有那么多独立的线程将导致更多的开销。但是,如果IO非常密集,那么拥有大量线程可能会有所帮助


NET 4引入了对并行编程的出色支持。如果这是您的一个选项,我建议您。

如果每个线程都将某些内容记录到您的ui中,那么每个写入的日志行都必须调用主线程。最好缓存日志输出,并仅每隔100次迭代或类似的时间更新gui。

因为我还没有看到您的代码,所以这只是很多猜测和一些非常有希望的猜测

线程池所做的只是将您的请求排队,然后在其他线程完成工作时启动新线程。现在3000个线程听起来并不多,但如果有大量的处理在进行,你可能会破坏你的CPU


我不相信后台工作人员会提供帮助,因为您最终将重新创建一个管理器来处理threadpool提供给您的所有池。我认为你更担心的是你有太多的数据块正在进行。我认为一个好的开始是限制你启动和维护的线程数量。threadpool管理器允许您轻松地执行此操作。找到一个平衡点,允许您在处理数据的同时保持UI的响应性。

我遇到了与此处描述的完全相同的问题,我有太多的信息从多个线程推送到ListView,应用程序很难跟进。要么实现某种队列将状态传递给UI,要么干脆不要将所有内容都推送到UI中。线程池在等待新线程时不会阻塞。它对所有线程请求进行排队。另外,您关于线程数等于
只有在CPU密集型工作时,内核才是正确的。如果是IO密集型任务,那么线程可能比内核多得多是有意义的。@Eric-因此,如果您的任务只是与CPU相关的HMMM,那么这个限定符就是。我应该先喝完我的第一杯咖啡:-对不起,刚刚通过资格赛。