从工作线程工作(WinForms)更新 GUI,为什么?

Update GUI from worker thread works (WinForms), why?

WinForms (VS2015 / .NET 4.6)

在我的后台线程中

 System.Threading.Tasks.Task.Run(() =>
 {
    ...
    _callback?.Progress("abcd");
    ...
 });

我调用了 GUI (_callback),它实现了 Form class 中的一个接口。 在这里,我修改了文本框、进度条等值。

void IWorkerCallback.Log(string message)
{
    _textBoxLog.AppendText($"{message}{Environment.NewLine}");
    ++_progressBar.Value;
    .... etc...
}

一切正常!
如果我使用调试器中断,我可以看到 Form.IWorkerCallback.Log() 函数在工作线程上下文中执行(在线程调试 window 中)。

到处都说你必须只在 GUI 线程(创建它们的地方)上更改 GUI 项目,否则你会得到 System.InvalidOperationException 异常 cross-thread operation not valid.....

但对我来说效果很好。

你能解释一下吗,为什么?

谢谢

运行 UI 来自另一个线程的调用是未定义的行为。它可能有效或无效。要在程序开头设置 Control.CheckForIllegalCrossThreadCalls = true; 的跨线程调用一致失败:

https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.control.checkforillegalcrossthreadcalls?view=netframework-4.8

来自 MSDN 文档:

When a thread other than the creating thread of a control tries to access one of that control's methods or properties, it often leads to unpredictable results. A common invalid thread activity is a call on the wrong thread that accesses the control's Handle property. Set CheckForIllegalCrossThreadCalls to true to find and diagnose this thread activity more easily.

在低 Windows API 级别,不使用线程本地存储或任何其他线程特定资源的跨线程 UI 调用可能会成功执行。但是,我们仍然有线程同步问题,所以结果也是未定义的。