13

別のスレッドで実行されているメソッドがあります。スレッドは、Windows アプリケーションのフォームから作成および開始されます。スレッド内から例外がスローされた場合、それをメイン アプリケーションに戻す最善の方法は何ですか。現在、メイン フォームへの参照をスレッドに渡し、スレッドからメソッドを呼び出し、メイン アプリケーション スレッドによってメソッドが呼び出されるようにしています。今のやり方に慣れていないので、これを行うためのベストプラクティスの方法はありますか?

私のフォームの例:

public class frmMyForm : System.Windows.Forms.Form
{
    /// <summary>
    /// Create a thread
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnTest_Click(object sender, EventArgs e)
    {
        try
        {
            //Create and start the thread
           ThreadExample pThreadExample = new ThreadExample(this);
           pThreadExample.Start();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, Application.ProductName);
        }
    }

    /// <summary>
    /// Called from inside the thread 
    /// </summary>
    /// <param name="ex"></param>
    public void HandleError(Exception ex)
    {
        //Invoke a method in the GUI's main thread
        this.Invoke(new ThreadExample.delThreadSafeTriggerScript(HandleError), new Object[] { ex });
    }

    private void __HandleError(Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

私のスレッドクラスの例:

public class ThreadExample
{
    public delegate void delThreadSafeHandleException(System.Exception ex);

    private Thread thExample_m;

    frmMyForm pForm_m;
    private frmMyForm Form
    {
        get
        {
            return pForm_m;
        }
    }

    public ThreadExample(frmMyForm pForm)
    {
        pForm_m = pForm;

        thExample_m = new Thread(new ThreadStart(Main));
        thExample_m.Name = "Example Thread";
    }

    public void Start()
    {
        thExample_m.Start();
    }

    private void Main()
    {
        try
        {
            throw new Exception("Test");
        }
        catch (Exception ex)
        {
            Form.HandleException(ex);
        }
    }
}
4

5 に答える 5

17

したがって、Invoke を使用して UI スレッドにマーシャリングしているのです。これは、まさにあなたが行う必要があることです。個人的には簡単にするために Action<Exception> を使用し、おそらく Invoke の代わりに BeginInvoke を使用しますが、基本的には正しいことをしています。

于 2008-10-09T20:08:42.237 に答える
5

代わりに、.NET フレームワークの BackgroundWorker クラスを使用してください。これは、別のスレッドで UI 作業を実行するためのベスト プラクティスです。

于 2008-10-20T21:20:02.577 に答える
2

おそらく、フォーム自体への参照ではなく、デリゲートをスレッドに渡す方がよいでしょう。

于 2008-10-09T20:09:48.880 に答える
1

スレッド間で例外をスローするのは簡単ではなく、おそらく望ましくありません。代わりに、共有データ構造または変数を使用して例外を渡し、waitHandle を使用して最初のスレッドで待機することができます。

于 2008-10-09T20:08:16.920 に答える
0

私はDrorに完全に同意します。正式な方法では、この構造を FaultContract と呼ぶことができます。基本的に、別のスレッドで例外が発生した場合、クライアント スレッドは、その情報を収集し、独自のスレッドで適切に動作すること以外、ほとんど何もできません。読み取りが別の AppPool にある場合、シリアライゼーションがさらに複雑になります (これは完全に別のトピックになる可能性があります)。

于 2012-08-16T11:10:45.050 に答える