C# 在不阻塞主线程的情况下执行长时间运行的UI更改
在C#winforms应用程序中,是否仍然可以运行大量UI更新而不影响主线程 我希望在用户单击特定事件时避免长时间延迟(在我的情况下,这是许多用于处理内存的关闭窗体调用) 我知道我可以使用C# 在不阻塞主线程的情况下执行长时间运行的UI更改,c#,.net,winforms,multithreading,backgroundworker,C#,.net,Winforms,Multithreading,Backgroundworker,在C#winforms应用程序中,是否仍然可以运行大量UI更新而不影响主线程 我希望在用户单击特定事件时避免长时间延迟(在我的情况下,这是许多用于处理内存的关闭窗体调用) 我知道我可以使用BackgroundWorker在“do work”事件中执行冗长的操作,但问题是在此事件中您无法更改任何UI(这将导致跨线程异常)-因此我无法将大量关闭表单调用放在此处 我不能将关闭窗体调用放在“worker completed”事件中,因为这是在主线程上运行的,最终会锁定主线程,从而导致糟糕的用户体验 我曾
BackgroundWorker
在“do work”事件中执行冗长的操作,但问题是在此事件中您无法更改任何UI(这将导致跨线程异常)-因此我无法将大量关闭表单调用放在此处
我不能将关闭窗体调用放在“worker completed”事件中,因为这是在主线程上运行的,最终会锁定主线程,从而导致糟糕的用户体验
我曾考虑过生成一个线程来处理只有在应用程序会话空闲时才会关闭的问题,但不确定这是否会有点混乱。您应该使用的事件来更新UI。要将实例的此功能集属性启用为true
。然后,您可以通过从事件处理程序发送数据来多次更新UI:
backgroundWorker.ReportProgress(percentage, yourCustomData);
建议将其删除。原因如下:
访问Windows窗体控件本身不是线程安全的。如果你
如果有两个或多个线程操纵控件的状态,则
可能会强制控件进入不一致的状态。其他
线程相关的bug也是可能的,包括争用条件
和僵局。确保访问您的控件非常重要
是以线程安全的方式完成的
NET Framework可帮助您检测何时访问
以非线程安全的方式进行控制。当你跑步的时候
您的应用程序位于调试器中,并且线程不是
它创建了一个试图调用该控件的控件,即调试器
引发InvalidOperationException,并显示消息“Control Control
从创建它的线程以外的线程访问的名称。“
此异常在调试期间可靠地发生,并且在某些情况下
环境,在运行时。强烈建议您解决此问题
当你看到它的时候,问题就来了
您可以禁用该异常:
Form.CheckForIllegalCrossThreadCalls = false;
但是控件可能(有时也会)停止工作。但这也在主线程上运行吗?据我所知,进程更改和完成的事件在主线程上运行任何UI更新都将在主线程上运行(线程,其中创建了控件)-winforms控件不是线程安全的谢谢,我认为情况就是这样。所以在我的场景中,我不能做太多,即使调用ProgressChanged,用户也会得到延迟?还是因为线程只是周期性地更改,所以他们不会注意到延迟?如果在ProgressChanged事件之间允许休眠,用户不会注意到…为什么关闭窗体调用要花费这么多时间?你们在做什么很费时。你们能把一个繁重的操作分成多个小的,然后分派到UI线程,这样UI线程就可以了吗?