1

先に進む前に、バックグラウンド ワーカーが終了するのを待つ必要があるアプリケーションがあります。バックグラウンド ワーカーは、初期化する USB デバイスにいくつかの値を書き込むことを担当します。バックグラウンド ワーカーの問題は、バックグラウンド ワーカーの初期化が完了する前にメイン プログラムが USB デバイスにアクセスしようとする可能性があることです。

バックグラウンド ワーカーが動作している間、UI スレッドはアニメーション化されたプログレス バーで「お待ちください」と表示します。プログレス バーは、バックグラウンド ワーカーの進行状況を反映していませ。単に「スピン」しているだけです。

バックグラウンドワーカーを使用しないといういくつかの質問を読みました。非同期で実行したくないためです(これは本当です)が、バックグラウンドワーカーを使用しないと、「お待ちください」ダイアログがブロックされ、実行されません。 t アニメーションを表示します。また、バックグラウンド ワーカーの使用をサポートする UI スレッドを 1 つだけ使用するようにとの指示もたくさん読みました。

また、「お待ちください」スピナーを別のスレッドに配置しようとしましたが、「お待ちください」ウィンドウが開く前に閉じようとする複雑さと奇妙な競合状態が発生します。

これについて正しい方法は何ですか?

4

4 に答える 4

4

それがまさにそのBackgroundWorkerために設計されたものです。これを達成する方法は他にもありますが、あなたがしていることは問題ありません。

于 2012-11-06T16:02:09.077 に答える
3

バックグラウンドワーカーを使用しないといういくつかの質問を読みました

まさにそれが設計されたものであるため、人々がこれを使用しないことを提案した理由を本当に知りません. 理想的には、スピナーとキャンセル オプションを含むモーダルダイアログを表示して、ユーザーが USB の書き込みプロセスを中断するのを UI によってブロックされるようにすることです。

書き込みプロセス中にボタンを無効にするだけでも十分です。

于 2012-11-06T16:02:18.680 に答える
2

が終了した後に実行する必要がある部分BackgroundWorker(-スクリプト) をBackgroundWorkerRunWorkerCompletedイベント ハンドラに入れます。

于 2012-11-06T16:30:22.477 に答える
2

あなたが解決しようとしている2つの別々の問題があると思います。

1 つ目は、メイン (UI) スレッドが初期化されていない USB デバイスにアクセスするのを防ぐ方法です。もう 1 つは、「お待ちください」スピナー ダイアログを処理しています。

私の提案は次のとおりです。

  1. BackgroundWworkerUSB デバイスの初期化の処理を続けます。
  2. クラスにブール値フィールドを追加して、USB デバイスの初期化が完了したときにフラグを立てます。

    private volatile bool _usbDeviceInited = false;

  3. バックグラウンド ワーカーが最後に行うことは、このフラグを に設定することtrueです。

  4. プロパティを使用して、USB デバイスへのアクセスを一元化します。USB の初期化が完了していない場合、getter メソッドは boolean フィールドを検査し、null 値を返す (または必要に応じて例外を発生させる) ことができます。
  5. コードを変更して、USB デバイスへのアクセスを許可するプロパティによって null が返されるかどうか (または、例外を発生させることを選択した場合は例外を処理するかどうか) を確認します。これは、使用する準備ができていないことを意味します。この状態を処理して、USB デバイスの準備ができていないことをユーザーに警告できます。

前の手順は、最初の問題を解決する 1 つの方法です。さて、スピナーです。

RunWorkerCompletedのイベントにサブスクライブすることをお勧めしますBackgroundWorker。メイン UI スレッドから作成された場合BackgroundWorker、イベントはメイン UIThread で発生します (つまり、ユーザー インターフェイス要素とやり取りしても安全です)。そこから、「お待ちください」ダイアログを閉じて破棄するだけです。また、プロパティをチェックしてAsyncCompletedEventArgs.Error、USB デバイスの初期化中に BackgroundWorker スレッドからエラー状態が発生していないことを確認する必要があります。

編集: あなたのアプリが USB デバイスにすぐにアクセスしようとするスクリプトを実行する可能性があることを読みました。私が提案したパターンを使用すると、次のように null 以外の値が返されるまで、スクリプトを実行する前にプロパティを「ポーリング」できます。

bool timedOut = false;
DateTime timeout = DateTime.Now.AddSeconds(timeoutSeconds);
while ( MyClass.MyUsbDevice == null ) {
   if( DateTime.Now > timeout ) {
      timedOut = true;
      break;
   }
   Thread.Sleep(0); // Avoid pegging the CPU, yield it to other processes
}

if( !timedOut ) {
   // run the script
} else {
   // Handle timeout
}

幸運を!

于 2012-11-06T16:29:28.393 に答える