有时,当调用Delegate.BeginInvoke时,执行委托方法需要一秒钟以上的时间。
延迟的原因可能是什么?在一个持续运行的应用程序中,我每天都会遇到1到2次这个问题。
请帮帮我。
谢谢!
发布于 2010-08-06 23:29:54
线程池管理器确保只允许执行与CPU核心一样多的线程。一旦一个任务完成,队列中等待的另一个任务将被允许执行。
每秒两次,它会重新评估正在运行的线程发生了什么。如果它们没有完成,它就认为它们被阻塞了,并允许另一个等待线程运行。在典型的双核CPU上,你会立即运行两个线程,第三个线程在一秒后启动,第四个线程在1.5秒后启动,依此类推。
好了,这是你的第二个。Q&D修复是使用ThreadPool.SetMinThreads(),但这是大锤解决方案。真正的问题是,您的程序正在为长时间运行的任务使用线程池线程。要么是因为它们执行了大量代码,要么是因为它们阻塞了某种类型的I/O请求。后者是更常见的情况。
解决这个问题的方法是,对于这样的阻塞线程,不使用线程池线程,而是使用thread类。如果线程真的在消耗CPU周期,请不要这样做,否则会减慢一切。很容易判断,您将在Taskmgr.exe中看到100%的cpu负载
发布于 2010-08-06 21:51:23
既然您使用的是Delegate.BeginInvoke,那么您就间接地使用了ThreadPool。ThreadPool回收已完成的线程,并允许重用它们,而无需花费构建新线程和拆卸已完成线程的成本。
所以..。当您使用Delegate.BeginInvoke时,您是在将要调用的方法添加到一个队列中,一旦ThreadPool认为它有可用于您的任务的线程,它就会执行。但是,如果ThreadPool超出了可用线程数,那么您将不得不等待。
System.Threading.ThreadPool有几个属性和方法来显示有多少线程可用,最大值等等。我会尝试监控这些计数,看看ThreadPool是否看起来正在变得稀疏。
如果是这种情况,那么最好的解决方案是确保ThreadPool仅用于短期(小型)任务。如果它被用于长时间运行的任务,那么这些任务应该被修改为使用它们自己的专用线程,而不是占用ThreadPool。
发布于 2010-08-06 21:38:05
你能设置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
https://stackoverflow.com/questions/3424179
复制相似问题