您可能知道,在 WinForm 项目中,UI 只能从单个线程处理。这被亲切地称为 UI 线程。这就是为什么在任何时候需要访问或修改 UI 元素时,都必须调用控件或表单的Invoke
方法。该Invoke
方法使给定的委托在 UI 线程上运行。但是,这样做不会中断 UI 线程已经在执行的任何处理。如果 UI 线程当前很忙,当你调用 时Invoke
,它会挂起,直到 UI 线程不再忙,然后它会执行给定的委托。
因此,在您的代码中,您正在启动一个新线程,该线程内部试图在 UI 线程上调用一个方法。但是,在启动新线程后,您会立即进入一个循环,使 UI 线程保持忙碌,直到另一个线程完成。因此,当您的新线程调用回 UI 线程时,UI 线程很忙,并且两个线程实际上都会永远挂起。
DoEvents
是一个关键字,您可以从 UI 线程中的冗长进程或循环中调用,以表明您想要暂停当前处理,从而释放 UI 线程来处理任何等待的窗口消息(绘制事件、单击事件、调用请求等)。一旦处理了所有这些待处理的窗口消息,它将返回执行您调用后的下一条语句DoEvents
。因此,如果DoEvents
在循环内调用使其正常工作,这意味着您的新线程必须调用回 UI 线程,或者在继续之前等待处理其他一些窗口消息。
打电话DoEvents
是危险的,并且被广泛认为是不好的做法。通常,如果您需要调用DoEvents
,这表明您需要重新考虑您的设计。通常有更好的方法来做你正在做的事情。
在您的情况下,似乎启动新线程完全没有意义。除非您已缩写代码,否则似乎只要您启动新线程,您只需将 UI 线程置于等待其他线程完成即可。如果是这种情况,那么简单地在 UI 线程本身上完成工作而不是开始一个新线程会更有意义。在您提供的代码中,没有两个线程将同时有效地进行处理,因此它并不比单个线程好。