2

現在、テスト ソフトウェアに自動保存機能を実装しようとしています。

「開始」ボタンは TestThread を起動してテストを行います。UI は TestThread からの Invokes を介して更新され、テスターに​​テストに関するリアルタイムの情報を提供します。ユーザーが「停止」ボタンをクリックすると、現在のテストを終了して停止するように TestThread に通知するフラグが設定されます。また、UI 上のコントロールを無効にし、StopThread を起動して TestThread の進行状況を監視します。TestThread が終了すると、StopThread は UI コントロールを再度有効にします。

この時点で、自動保存 (Excel ファイルの生成につながる SaveFileDialog) を呼び出すことができるように、StopThread が終了するのを待つ必要があります。ただし、「停止」ボタンのクリック ハンドラで StopThread.Join() を使用すると、プログラムがハングするだけのようです。これは、TestThread が完了するまでに時間がかかり、ブロックされた UI スレッドを更新しようとするためと考えられます。

SaveFileDialog (モーダル フォーム) を使用し、呼び出し元のスレッドを「シングル スレッド アパートメント」に設定する必要があるため、StopThread から保存関数を呼び出すと ThreadStateException が生成されます。

これを検索すると、Thread.Join() を使用するだけで一般的な回答が得られるようです。スレッドが終了するまでUIをアクティブにしておく必要があるという単純な事実により、これは使用できなくなります。SaveFileDialog を StopThread から呼び出して UI スレッドにマーシャリングする方法はありますか? 他の提案はありますか?前もって感謝します。

作業ソリューション:

private void btn_Stop_Click(object sender, EventArgs e)
    {
        //Disable UI controls and flag test ending

        Thread StopThread = new Thread(WaitForTestEnd);
        StopThread.Start();        
    }

    private void WaitForTestEnd()
    {
        while (!testStopped) //Flag set at end of TestThread
        {
            Thread.Sleep(50);
        }

        //Re-enable UI

        AutoSave saveMyData = SaveData;
        Invoke(saveMyData);
    }

    private delegate void AutoSave();

    private void SaveData()
    {
        //Generate SaveFileDialog and save.
    }
4

2 に答える 2

3

まったくブロックしないでくださいStopThread。代わりにStopThread、それが終了したことをメインスレッドに通知するように配置します。たとえば、を使用しInvokeます。

于 2012-05-18T14:21:00.523 に答える
1

StopThreadからSaveFileDialogを呼び出して、UIスレッドにマーシャリングする方法はありますか?

TestThreadの場合とまったく同じように、Control.Invokeまたはを使用してみませんか?Dispatcher.Invoke

于 2012-05-18T14:21:15.967 に答える