Delegate.BeginInvoke 延迟
有时,当调用 Delegate.BeginInvoke 时,执行委托方法需要超过一秒的时间。
延迟的原因可能是什么?我在连续运行的应用程序中每天会遇到此问题 1 或 2 次。
请帮我。
谢谢!
Sometimes when Delegate.BeginInvoke is invoked, it takes more than one second to execute the delegate method.
What could be the reasons for the delay? I get this issue 1 or 2 times a day in an application which runs continuosly.
Please help me.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
线程池管理器确保只允许执行与 CPU 核心数量相同的线程。一旦一个完成,队列中等待的另一个就可以执行。
它每秒两次重新评估正在运行的线程的情况。如果它们没有完成,则假定它们被阻塞并允许另一个等待线程运行。在典型的双核 CPU 上,您将立即运行两个线程,第三个线程在一秒后启动,第四个线程在 1.5 秒后启动,依此类推。
好吧,这是你的第二个。 Q&D 修复方法是使用 ThreadPool.SetMinThreads(),但这是一个大锤解决方案。真正的问题是您的程序正在使用线程池线程来执行长时间运行的任务。要么是因为它们执行了大量代码,要么是因为它们阻塞了某种 I/O 请求。后者是更常见的情况。
解决这个问题的方法是不使用线程池线程来处理这样的阻塞线程,而是使用 Thread 类。如果线程实际上正在消耗 CPU 周期,请不要这样做,否则会减慢一切。很容易看出,您会在 Taskmgr.exe 中看到 100% cpu 负载
The thread pool manager makes sure that only as many threads are allowed to execute as you have CPU cores. 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.
Well, there's your second. The Q&D fix is to use ThreadPool.SetMinThreads(), but that's the sledgehammer solution. 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. 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. Don't do this if the threads are actually burning CPU cycles, you'll slow everything down. Easy to tell, you'll see 100% cpu load in Taskmgr.exe
由于您使用的是
Delegate.BeginInvoke
,那么您就间接地使用了ThreadPool
。 ThreadPool 回收已完成的线程并允许重复使用它们,而无需花费构建新线程和拆除已完成线程的费用。所以...当您使用
Delegate.BeginInvoke
时,一旦ThreadPool
认为它有可用的线程,您就将要调用的方法添加到队列中。它将执行的任务。但是,如果ThreadPool
没有可用线程,那么您将不得不等待。System.Threading.ThreadPool 有几个属性和方法来显示可用线程数、最大值等。我会尝试监视这些计数,看看它是否看起来像 ThreadPool正在被分散。
如果是这种情况,那么最好的解决方案是确保
ThreadPool
仅用于短期(小)任务。如果它用于长时间运行的任务,那么这些任务应该修改为使用它们自己的专用线程,而不是占用线程池。Since you're using
Delegate.BeginInvoke
then you're, indirectly, using theThreadPool
. TheThreadPool
recycles completed threads and allows them to be reused without going through the expense of constructing new threads and tearing completed threads down.So... when you use
Delegate.BeginInvoke
you're adding the method to be invoked to a queue, as soon as theThreadPool
thinks it has an available thread for your task it will execute. However, if theThreadPool
is out of available threads then you'll be left waiting.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 theThreadPool
is being spread thin.If that's the case then the best resolution is to ensure that the
ThreadPool
is only being used for short-lived (small) tasks. 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.可以设置BeginInvoke的优先级吗?
http://msdn.microsoft.com/en- us/library/system.windows.threading.dispatcherpriority.aspx
您是否还有其他 BeginInvoke 调用在等待?
“如果以相同的 DispatcherPriority 进行多个 BeginInvoke 调用,它们将按照调用的顺序执行。”
http://msdn.microsoft.com/en-us/library/ms591206。 ASPX
Can you set the priority of the BeginInvoke?
http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherpriority.aspx
Do you have other BeginInvoke calls waiting?
"If multiple BeginInvoke calls are made at the same DispatcherPriority, they will be executed in the order the calls were made."
http://msdn.microsoft.com/en-us/library/ms591206.aspx