有时,当调用Delegate.BeginInvoke时,执行委托方法需要一秒以上的时间。
延迟的原因是什么?我在一个连续运行的应用程序中每天发出1到2次这个问题。
请帮帮我。
谢谢!
答案 0 :(得分:7)
线程池管理器确保只允许执行与CPU内核一样多的线程。一旦完成,就允许另一个在队列中等待的人执行。
每秒两次,它会重新评估正在运行的线程的运行情况。如果它们没有完成,则假定它们被阻止并允许另一个等待线程运行。在典型的双核CPU上,你将立即运行两个线程,第三个线程在一秒钟后启动,第四个线程在1.5秒后启动,等等。
嗯,这是你的第二个。 Q& D修复是使用ThreadPool.SetMinThreads(),但这是大锤解决方案。真正的问题是您的程序正在使用线程池线程来执行长时间运行的任务。要么是因为它们执行了大量代码,要么是因为它们阻塞了某种I / O请求。后者是更常见的情况。
解决问题的方法是不为这样的阻塞线程使用线程池线程,而是使用Thread类。如果线程实际上正在燃烧CPU周期,那么不要这样做,你会减慢一切。很容易说,你会在Taskmgr.exe中看到100%的cpu负载
答案 1 :(得分:4)
由于您使用的是Delegate.BeginInvoke
,因此您间接使用ThreadPool
。 ThreadPool
回收已完成的线程并允许它们重复使用,而无需花费构建新线程和撕掉已完成线程的费用。
所以......当你使用Delegate.BeginInvoke
时,你要将要调用的方法添加到队列中,只要ThreadPool
认为它有一个可用的任务线程就会执行它。但是,如果ThreadPool
超出可用线程,那么您将等待。
System.Threading.ThreadPool
有几个属性和方法来显示有多少线程可用,最大值等。我会尝试监视这些计数,看看ThreadPool
是否正在变薄。
如果就是这种情况,那么最佳解决方案是确保ThreadPool
仅用于短期(小)任务。如果它被用于长时间运行的任务,则应修改这些任务以使用自己的专用线程而不是占用ThreadPool。
答案 2 :(得分:2)
您可以设置BeginInvoke的优先级吗?
http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherpriority.aspx
您还有其他的BeginInvoke呼叫在等待吗?
“如果在同一个DispatcherPriority上进行了多次BeginInvoke调用,它们将按照调用的顺序执行。”