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