从工作线程工作(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;
的跨线程调用一致失败:
来自 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 调用可能会成功执行。但是,我们仍然有线程同步问题,所以结果也是未定义的。
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;
的跨线程调用一致失败:
来自 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 调用可能会成功执行。但是,我们仍然有线程同步问题,所以结果也是未定义的。