1)不要RunWorkerAsync
作为调用的方法。它实际上并没有运行您认为的方法。你真正应该放的东西是这样的:
this.Invoke(new MethodInvoker(MethodToUpdateUI));
MethodToUpdateUI
应该是您创建的一些新方法,专门执行在此上下文中应进行的任何 UI 更新。
2) 不需要InvokeRequired
. 你在后台线程中。总是需要调用。
老实说,整个模式if(invoke required) call myself else do stuff
是一个我不喜欢的奇怪结构。 InvokeRequired
应该很少使用。你应该几乎总是知道你是在 UI 线程还是后台线程,如果你不知道,很可能有问题(要么你总是在一个或另一个,你只是不知道哪个,或者它不应该是不确定的)。通常这意味着拥有必须在 UI 线程中运行的方法。如果您已经在 UI 线程中,您只需调用它们,如果您在后台线程中并且知道它,那么您Invoke
首先调用。
最重要的是,Invoke
即使您已经在 UI 线程中调用它也可以正常工作,因此Invoke
无论您是在后台线程中还是已经在 UI 线程中,调用都不会产生明显的负面影响。
3) 通常最好将解决业务问题的代码与 UI 代码分开。从 DoWork 的处理程序中调用是代码异味。如果这即将结束,您可能应该将事件处理程序添加到RunWorkerCompleted
. 如果您定期调用它以使用工作人员的进度更新 UI,那么您应该正在使用ReportProgress
和处理该ProgressReported
事件。要从 UI 获取信息以用于长时间运行的任务,您应该在启动后台任务之前访问它。对于不属于上述任何一种的特殊情况,使用 可能是合适的Invoke
,但其余情况应该很少见。