我们有一个桌面应用程序,它在后台线程中执行非常严格的计算。此计算的一部分在我们通过互操作访问的非托管库中执行。我们发现的是,当我们开始计算时,UI线程在计算期间变得没有响应。我们的印象是框架将处理线程切换以允许UI继续响应,但事实并非如此。我们发现可以插入Thread.Sleep(0)或Application.DoEvents()以允许UI响应。这具有减慢计算的副作用。此外,非托管代码执行的部分计算可能需要30秒才能完成,在此期间应用程序始终无响应。整个计算可能需要两到五分钟才能完成。
这导致以下问题:
答案 0 :(得分:2)
您可以降低后台线程的优先级,因此操作系统会更多地抢占它。如果你有一些领域知识导致你想要控制何时被抢占,你可以使用Thread.Sleep(0),如果有另一个线程在等待,你就会放弃你的时间片。
Application.DoEvents泵送Windows消息队列。这将导致您的应用响应键击或窗口调整大小等事件。 Thread.Sleep将导致你的线程被抢占(或者在Thread.Sleep(0)的情况下可能不被抢占)。
另请阅读Threading in C#
答案 1 :(得分:2)
您最好的选择是创建自己的Thread
。 DoEvents
和Thread.Sleep(0)
会阻止计算,从而减慢计算速度。您可以将DLL调用包装在ThreadStart
委托或ParameterizedThreadStart
委托中,并在实例化Thread
时将委托名称用作参数。从那里,您所要做的就是调用Thread
的Start方法。
答案 2 :(得分:0)
这样做的正确方法是使用回调。请参阅使用异步方法的Silverlight模型(例如,用于检索Web服务数据)。我知道这个问题是“回答”但答案并不理想恕我直言。