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

问题描述 投票:0回答:1

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.....异常

但是对我来说很好。

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

谢谢

multithreading winforms controls
1个回答
0
投票

从另一个线程运行UI调用是未定义的行为。它可能行不通。要在跨线程调用中获得一致的失败,请在程序开头设置Control.CheckForIllegalCrossThreadCalls = true;

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

从MSDN文档:

当控件的创建线程以外的线程尝试访问该控件的方法或属性之一时,通常会导致不可预测的结果。常见的无效线程活动是对访问控件的Handle属性的错误线程的调用。将CheckForIllegalCrossThreadCalls设置为true可以更轻松地查找和诊断此线程活动。

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

© www.soinside.com 2019 - 2024. All rights reserved.