为什么我没有得到"跨线程操作无效"错误

pel*_*elz 5 .net c# multithreading exception-handling winforms

我使用BackgroundWorker并执行此操作:

private void loadNewAsyncToolStripMenuItem_Click(object sender, EventArgs e)
{
    this.Text = "RunWorkerAsync()";
    backgroundWorkerLoading.RunWorkerAsync();
}
private void backgroundWorkerLoading_DoWork(object sender, DoWorkEventArgs e)
{
    UnsafeThreadMethod("hello");
    EvenUnsaferThreadMethod();
}
Run Code Online (Sandbox Code Playgroud)

而现在这两种方法.

private void UnsafeThreadMethod(string text)
{
    toolStripLabelRssFeedData.Text = text;
}

private void EvenUnsaferThreadMethod()
{
    panelLoading.Visible = true;
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么UnsafeThreadMethod不抛出以下异常,但EvenUnsaferThreadMethod确实如此.

跨线程操作无效:控制'panelLoading'从其创建的>线程以外的线程访问.

根据消息,因为toolStripLabelRssFeedData它是在同一个线程上创建的,但事实并非如此.

我以为我不能调用主线程创建的控件并且必须使用该ProgressChanged事件.这是怎么回事?

我还有第二个问题.当我可以使用时,这样做有什么好处ProgressChanged?我该怎么办?

private void EvenUnsaferThreadMethod()
{
    if (panelLoading.InvokeRequired)
    {
        panelLoading.Invoke(new MethodInvoker(() => { EvenUnsaferThreadMethod(); }));
    }
    else
    {
        panelLoading.Visible = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

Hen*_*man 5

对第一个问题:

  • 在调试模式下故意抛出跨线程异常.这意味着对大多数GUI控件中内置的InvokeRequired进行(条件)代码检查.像小组一样.

  • 显然,ToolstripLabel不进行此检查.因为它不是来自Control,可能是因为它超出了本安全网的范围.

由于标准免责声明"任何实例成员都不保证是线程安全的"适用于ToolstripLabel,因此在设置Text时我会使用普通的InvokeRequired逻辑.