2

スレッド A で例外をキャッチし、例外オブジェクトをスレッド B に渡し、スレッド B からスローしたいのですが、安全ですか?

スレッドA

try {
    // Code that throws exceptions
} catch (Exception e) {
    sendToOtherThread(e);
}

スレッド B

Exception e = receiveException();
throw e;

編集

わかりやすくするために、スレッドの仕組みと、あるスレッドから別のスレッドにオブジェクト参照を渡す方法を理解しています。問題は、例外オブジェクトを作成していないスレッドから例外オブジェクトをスローしても安全かどうか、またはクラスException自体または .NET がそれを処理する方法に問題があるかどうかです。

4

5 に答える 5

1

.NET 4.0の使用を検討している場合、aによってスローされた例外Taskは、が結合されたときに親スレッドに自動的に伝播されますTask。これは仕様によるものであり、完全に安全である必要があります。こちらをご覧ください:http://msdn.microsoft.com/en-us/library/dd997415.aspx

于 2012-07-04T10:25:07.977 に答える
1

別のスレッド (たとえば、BackgroundWorker の RunWorkerCompleted イベント ハンドラー) から受け取った例外を再スローできますが、スタック トレースを保持するために別の例外でラップする方が一般的です。

private void backgroundWorker1_RunWorkerCompleted(
    object sender, RunWorkerCompletedEventArgs e)
{
    // First, handle the case where an exception was thrown.
    if (e.Error != null)
    {
        throw new SomeException("... message ...", e.Error);
    }
    ...
}
于 2012-07-04T10:27:42.453 に答える
0

これを変更する必要があります:

スレッドBで

Exception e = receiveException();
throw new Exception("Write something here, for example: 'Received from other thread'", e); // so you keep the stack trace

ただし、注意点に注意します(これが100%安全かどうかは完全にはわかりません)。

于 2012-07-04T09:51:20.883 に答える
0

安全なはずですが、おそらくスレッド B が終了します。

ソリューションは、例外オブジェクトをスレッド A からスレッド B に渡す方法にのみ依存します。共有リソースに配置する場合は、その特定の共有リソースをロックして解放する必要があります。それ以外に、コードに安全でないものはありません。

スレッド内の共有リソースにアクセスしていない限り、他のすべては安全です。

于 2012-07-04T10:01:02.797 に答える
0

Exceptionはクラスであり、したがって標準の参照型です。スレッド間で渡したい場合 (これは少し奇妙に聞こえます)、他の誰もインスタンスを変更しようとしないことを確認する必要があります (特に、独自の変更可能な例外型を作成する場合)

解決策 A
Producer-Consumer プルモデルを実行できます

BlockingCollection<Exception> bc = new BlockingCollection<Exception>();

// thread A - Producer
try
{
    ...
}
catch(Exception ex)
{
    bc.Add(ex);
}


//thread B - Consumer
try
{
    // Consume bc
    while (true)
    {
        var ex = bc.Take();
        //thread sleep
    }
}
catch (InvalidOperationException)
{
    // IOE means that Take()
    // was called on a completed collection and no
    // No more exceptions, restart checking    
}

解決策 B
しかし、リソースを浪費する可能性があるため、プル モデルを使用せず、スレッド セーフな監視可能なコレクションを使用してプッシュ モデルを使用することをお勧めします。

于 2012-07-04T10:01:35.290 に答える