4

我有一个小应用程序,它实现了一个基于 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 内部调用时,它会引发异常,从创建它的线程以外的线程访问的消息控件“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);
    }
}

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

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

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

还是我错过了什么?

提前致谢!

4

1 回答 1

7

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

这种行为可以通过CheckForIllegalCrossThreadCalls来控制,这是一个暴露在Control类上的静态属性。我强烈建议不要禁用它,抛出这些异常是为了让开发人员知道他们的多线程可能非常错误(-Control派生类不是线程安全的)

于 2013-09-12T11:24:55.353 回答