現在、テスト ソフトウェアに自動保存機能を実装しようとしています。
「開始」ボタンは 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.
}