【发布时间】:2019-12-11 14:43:08
【问题描述】:
WinForms (VS2015 / .NET 4.6)
在我的后台线程中
System.Threading.Tasks.Task.Run(() =>
{
...
_callback?.Progress("abcd");
...
});
我调用 GUI (_callback),它在 Form 类中实现了一个接口。 在这里,我修改了文本框、进度条等值。
void IWorkerCallback.Log(string message)
{
_textBoxLog.AppendText($"{message}{Environment.NewLine}");
++_progressBar.Value;
.... etc...
}
一切正常!
如果我使用调试器,我可以看到Form.IWorkerCallback.Log() 函数在工作线程上下文中执行(在线程调试窗口中)。
到处都说您必须仅在 GUI 线程(创建它们的位置)上更改 GUI 项目,否则您会得到 System.InvalidOperationException 异常 cross-thread operation not valid.....
但这对我来说很好用。
你能解释一下,为什么?
谢谢
【问题讨论】:
-
这是未定义的行为。它可能有效,也可能无效。要在跨线程调用上获得一致的失败,请在程序开头设置
Control.CheckForIllegalCrossThreadCalls = true。 -
docs.microsoft.com/en-us/dotnet/api/… 在较低的 Windows API 级别上,不使用线程本地存储或任何其他线程特定资源的跨线程 UI 调用可能会成功执行。
-
@AlexF - 是的,就是这样,
Control.CheckForIllegalCrossThreadCalls是诀窍!如果你把它写成答案,我会接受它。 -
这就是BeginInvoke() 的用途。它可以从不同的线程或主线程调用。您无需查看
InvokeRequired。无需考虑是否附加了调试器。 -
是的,我知道,但很惊讶它可以在没有 begininvoke() 的情况下工作
标签: multithreading winforms controls