.NET线程模型和Application.DoEvents与Thread.Sleep

时间:2009-04-28 15:32:04

标签: .net multithreading

我们有一个桌面应用程序,它在后台线程中执行非常严格的计算。此计算的一部分在我们通过互操作访问的非托管库中执行。我们发现的是,当我们开始计算时,UI线程在计算期间变得没有响应。我们的印象是框架将处理线程切换以允许UI继续响应,但事实并非如此。我们发现可以插入Thread.Sleep(0)或Application.DoEvents()以允许UI响应。这具有减慢计算的副作用。此外,非托管代码执行的部分计算可能需要30秒才能完成,在此期间应用程序始终无响应。整个计算可能需要两到五分钟才能完成。

这导致以下问题:

  • 关于UI和interop的.NET框架线程模型是什么?
  • 假设框架应该处理后台和UI线程之间的线程切换,我们是不正确的?
  • 在这种情况下使用Thread.Sleep和Application.DoEvents有什么区别,并且优先于另一个?

3 个答案:

答案 0 :(得分:2)

您可以降低后台线程的优先级,因此操作系统会更多地抢占它。如果你有一些领域知识导致你想要控制何时被抢占,你可以使用Thread.Sleep(0),如果有另一个线程在等待,你就会放弃你的时间片。

Application.DoEvents泵送Windows消息队列。这将导致您的应用响应键击或窗口调整大小等事件。 Thread.Sleep将导致你的线程被抢占(或者在Thread.Sleep(0)的情况下可能不被抢占)。

另请阅读Threading in C#

答案 1 :(得分:2)

您最好的选择是创建自己的ThreadDoEventsThread.Sleep(0)会阻止计算,从而减慢计算速度。您可以将DLL调用包装在ThreadStart委托或ParameterizedThreadStart委托中,并在实例化Thread时将委托名称用作参数。从那里,您所要做的就是调用Thread的Start方法。

答案 2 :(得分:0)

这样做的正确方法是使用回调。请参阅使用异步方法的Silverlight模型(例如,用于检索Web服务数据)。我知道这个问题是“回答”但答案并不理想恕我直言。