4

MEF に基づくプラグイン システムを実装する小さなアプリがあります。アプリケーションはプラグインを動的にロードし、新しいプラグインはいつでも plugins フォルダーに配置できます。これを実現するために、自動再構成と、新しいパーツが利用可能になったときに発生する 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);
}

上記のメソッドがメイン フォーム ctor のように UI スレッドから呼び出された場合、すべて問題ありませんでした。しかし、新しいプラグインを plugins フォルダーに配置するとすぐに、このメソッドが呼び出され、「通常の実行」(VS 2010 の外部から、または ctrl+F5 を介してアプリを呼び出す) では、動作しているように見えました。新しいプラグインのリストボックスは、VS 2010 内から F5 (デバッグ) で呼び出すと、作成されたスレッド以外のスレッドからアクセスされる bessage 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);
    }
}

私の質問は、デバッグ モードでのみ例外が発生した理由です。

リリース モードではアクティブではないこの種のクロススレッドの問題をチェックする、デバッグ モードでアクティブになるオプションはありますか?

問題はリリースモードにあると思いますが、何らかの理由でチェックされていないため表示されません。

または、何か不足していますか?

前もって感謝します!

4

1 に答える 1

7

これらの例外は、デバッガーがプロセスに接続されている場合にのみチェックされるため、デバッグなしで (または VS の外部でスタンドアロンで) プロセスを実行している場合は表示されません。

この動作は、クラスで公開されている静的プロパティであるCheckForIllegalCrossThreadCallsによって制御できます。Controlただし、無効にしないことを強くお勧めします。これらの例外は、開発者にマルチスレッドに重大な問題がある可能性があることを知らせるためにスローされます (-Control派生クラスはスレッドセーフではありません)。

于 2013-09-12T11:24:55.353 に答える