【问题标题】:Why the cross-threading exception raises only when debugging? [duplicate]为什么只有在调试时才会引发跨线程异常? [复制]
【发布时间】:2013-09-12 11:12:38
【问题描述】:

我有一个小应用程序,它实现了基于 MEF 的插件系统。 应用程序动态加载插件,新插件可以随时放在插件文件夹中。 为了实现这一点,我使用了自动重组和事件 Changed,当有新零件可用时会引发该事件。 当某些新部件可用时,我会更新 UI 中的列表框。

导致问题的代码在 Changed 事件触发时调用的方法中:

public void OnUserViewPluginCatalogChanged
             (object sender, ComposablePartCatalogChangeEventArgs e)
{
    listBox1.Items.Clear();
    foreach (var item in fPluginStore.PluginsAvailable)
        listBox1.Items.Add(item.Metadata["Caption"] as string);
}

当从 UI 线程调用上述方法时,就像在 Main Form ctor 中一样,一切正常。但是,只要我将一个新插件放在插件文件夹中,就会调用此方法,并且在“正常执行”(从 VS 2010 外部或通过 ctrl+F5 调用应用程序)时,它似乎可以工作,显示在新插件列表框,当使用 F5(调试)从 VS 2010 内部调用时,它会引发异常 Control 'listbox1' 从创建它的线程以外的线程访问

我通过下面的代码解决了这个问题:

public void OnUserViewPluginCatalogChanged
             (object sender, ComposablePartCatalogChangeEventArgs e)
{
    if( listBox1.InvokeRequired )
    {            
        this.Invoke((MethodInvoker) delegate { listBox1.Items.Clear(); });
        foreach (var item in fPluginStore.PluginsAvailable)
            this.Invoke((MethodInvoker) delegate 
                        {listBox1.Items.Add(item.Metadata["Caption"] as string);});
    }
    else
    {    
        listBox1.Items.Clear();
        foreach (var item in fPluginStore.PluginsAvailable)
           listBox1.Items.Add(item.Metadata["Caption"] as string);
    }
}

我的问题是为什么只在调试模式下引发异常?

是否有一个在调试模式下处于活动状态的选项可以检查这种在发布模式下不活动的跨线程问题?

我假设问题出在发布模式中,但由于某种原因它没有显示出来,因为没有被检查。

还是我错过了什么?

提前致谢!

【问题讨论】:

  • 在创建这个之前,我与提到的线程交叉,但由于标题的原因,我认为这是另一回事。抱歉,重复发布。并感谢您指出。

标签: c# multithreading winforms debugging mef


【解决方案1】:

只有在调试器附加到进程时才会检查这些异常,因此在没有调试(或独立于 VS 之外)运行进程时它们不会显示。

可以通过CheckForIllegalCrossThreadCalls 控制此行为,Control 类上公开的静态属性。我强烈建议不要禁用它,抛出这些异常是为了让开发人员知道他们的多线程可能存在非常大的问题(Control 派生类不是线程安全的)

【讨论】:

  • 感谢您的解释。
猜你喜欢
  • 1970-01-01
  • 2016-12-29
  • 1970-01-01
  • 1970-01-01
  • 2020-03-13
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多