简体   繁体   English

Delegate.BeginInvoke延迟

[英]Delegate.BeginInvoke Delay

Sometimes when Delegate.BeginInvoke is invoked, it takes more than one second to execute the delegate method. 有时,当调用Delegate.BeginInvoke时,执行委托方法需要一秒以上的时间。

What could be the reasons for the delay? 延迟的原因是什么? I get this issue 1 or 2 times a day in an application which runs continuosly. 我在一个连续运行的应用程序中每天发出1到2次这个问题。

Please help me. 请帮我。

Thanks! 谢谢!

The thread pool manager makes sure that only as many threads are allowed to execute as you have CPU cores. 线程池管理器确保只允许执行与CPU内核一样多的线程。 As soon as one completes, another one that's waiting in the queue is allowed to execute. 一旦完成,就允许另一个在队列中等待的人执行。

Twice a second, it re-evaluates what's going on with the running threads. 两秒钟,它重新评估正在运行的线程正在发生的事情。 If they don't complete, it assumes they are blocked and allows another waiting thread to run. 如果它们没有完成,则假定它们被阻止并允许另一个等待线程运行。 On the typical two-core CPU, you'll get two threads running right away, the 3rd thread starts after one second, the 4th thread after 1.5 second, etcetera. 在典型的双核CPU上,你将立即运行两个线程,第三个线程在一秒后启动,第四个线程在1.5秒后启动,等等。

Well, there's your second. 嗯,这是你的第二个。 The Q&D fix is to use ThreadPool.SetMinThreads(), but that's the sledgehammer solution. Q&D修复是使用ThreadPool.SetMinThreads(),但这是大锤解决方案。 The real issue is that your program is using thread pool threads for long-running tasks. 真正的问题是您的程序正在使用线程池线程来执行长时间运行的任务。 Either because they execute a lot of code or because they block on some kind of I/O request. 要么是因为它们执行了大量代码,要么是因为它们阻塞了某种I / O请求。 The latter being the more common case. 后者是更常见的情况。

The way to solve it is to not use a thread pool thread for such a blocking thread but use the Thread class instead. 解决它的方法是不要将线程池线程用于这样的阻塞线程,而是使用Thread类。 Don't do this if the threads are actually burning CPU cycles, you'll slow everything down. 如果线程实际上正在燃烧CPU周期,那么不要这样做,你会减慢一切。 Easy to tell, you'll see 100% cpu load in Taskmgr.exe 很容易说,你会在Taskmgr.exe中看到100%的cpu负载

Since you're using Delegate.BeginInvoke then you're, indirectly, using the ThreadPool . 由于您正在使用Delegate.BeginInvoke因此您间接使用ThreadPool The ThreadPool recycles completed threads and allows them to be reused without going through the expense of constructing new threads and tearing completed threads down. ThreadPool回收已完成的线程并允许它们被重用,而无需花费构建新线程和撕掉已完成线程的费用。

So... when you use Delegate.BeginInvoke you're adding the method to be invoked to a queue, as soon as the ThreadPool thinks it has an available thread for your task it will execute. 所以...当你使用Delegate.BeginInvoke你要将要调用的方法添加到队列中,一旦ThreadPool认为它有一个可用的线程,它将执行它。 However, if the ThreadPool is out of available threads then you'll be left waiting. 但是,如果ThreadPool没有可用的线程,那么你将等待。

System.Threading.ThreadPool has several properties and methods to show how many threads are available, maximums, etc. I would try monitoring those counts to see if it looks like the ThreadPool is being spread thin. System.Threading.ThreadPool有几个属性和方法来显示有多少线程可用,最大值等。我会尝试监视这些计数,看看它是否看起来像ThreadPool正在传播。

If that's the case then the best resolution is to ensure that the ThreadPool is only being used for short-lived (small) tasks. 如果是这种情况,那么最好的解决方案是确保ThreadPool仅用于短期(小)任务。 If it's being used for long-running tasks then those tasks should be modified to use their own dedicated thread rather than occupying the ThreadPool. 如果它被用于长时间运行的任务,那么应该修改这些任务以使用他们自己的专用线程而不是占用ThreadPool。

Can you set the priority of the BeginInvoke? 你能设置BeginInvoke的优先级吗?

http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherpriority.aspx http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherpriority.aspx

Do you have other BeginInvoke calls waiting? 你还有其他的BeginInvoke电话在等吗?

"If multiple BeginInvoke calls are made at the same DispatcherPriority, they will be executed in the order the calls were made." “如果在同一个DispatcherPriority上进行了多次BeginInvoke调用,它们将按照调用的顺序执行。”

http://msdn.microsoft.com/en-us/library/ms591206.aspx http://msdn.microsoft.com/en-us/library/ms591206.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM