在不阻塞主线程的情况下执行长时间运行的UI更改

无论如何在没有影响C#winforms应用程序中的主线程的情况下运行大量UI更新?

当用户点击某个特定事件时,我希望避免长时间的延迟(在我的情况下,这是一个非常接近forms的处理内存的调用)

我知道我可以使用BackgroundWorker在“do work”事件中执行冗长的操作,但问题是你不能在这个事件中更改任何UI(它会导致交叉线程exception) – 所以我不能把我的大量关闭在这里打电话。

而且我不能将关闭forms调用放在“工作完成”事件中,因为这是在主线程上运行的,并且最终将锁定主线程导致糟糕的用户体验。

我已经考虑过只在应用程序会话空闲时才产生一个处理关闭的线程,但不确定这是否会有点混乱。

您应该使用BackgroundWorker的 ProgressChanged事件来更新UI。 要启用此function,请将BackgroundWorker实例的WorkerReportsProgress属性设置为true 。 然后,您可以通过从DoWork事件处理程序发送数据来多次更新UI:

 backgroundWorker.ReportProgress(percentage, yourCustomData); 

建议对Windows窗体控件进行线程安全调用 。 原因如下:

对Windows窗体控件的访问本质上不是线程安全的。 如果您有两个或多个线程来操纵控件的状态,则可以强制控件进入不一致状态。 其他与线程相关的错误也是可能的,包括竞争条件和死锁。 确保以线程安全的方式访问控件非常重要。

.NET Framework可帮助您以非线程安全的方式检测何时访问控件。 当您在调试器中运行应用程序时,除了创建控件的线程之外的线程尝试调用该控件时,调试器会引发一个InvalidOperationException,并显示消息“从该线程以外的线程访问控制控件名称”创建于。”

在调试期间以及在某些情况下在运行时可靠地发生此exception。 强烈建议您在看到此问题时解决此问题。

您可以禁用该exception:

 Form.CheckForIllegalCrossThreadCalls = false; 

但控制可能(有时会)停止工作。