2
  1. 2 つの UI スレッドがあります。1 つはメイン スレッドで、もう 1 つは ApartmentState が STA であるバックグラウンド スレッドです。各スレッドは独自のウィンドウを作成し、バックグラウンド ウィンドウには「キャンセル」ボタンがあります。

  2. メイン スレッドには、ビジー状態で完了するまでにかなりの時間を必要とする関数があります。「キャンセル」ボタンをクリックしたら、メインスレッドが時間のかかる機能を停止することを願っています。

  3. 以下は、メインスレッドの疑似コードです。

    為に(...) {

      //Option A: Application.DoEvents(); 
      //Option B: Dispatcher.Invoke to update UI in background thread
      if(cancel)    
        return;  //Stop the time-consuming function
      else     
        DoSomething;
    

    }

奇妙なことに、[キャンセル] ボタンのクリック イベントは、バックグラウンド スレッドによってキャプチャまたは処理されません。IMO、各スレッドには独自のメッセージキューがあり、「キャンセル」ボタンをクリックすると、このメッセージはキューに入れられ、バックグラウンドスレッドによってすぐに処理されるはずですが、ローカルでのテストによると、これは正しくありません。バックグラウンドスレッドは決して処理しませんボタンクリックイベント...

何かご意見は?

ところで、上記の問題を解決するには 2 つの方法があると思います。1 つは Application.DoEvents を使用する方法で、もう 1 つは Dispatcher.Invoke を利用する方法です。しかし、なぜバックグラウンド スレッドがメッセージをすぐに処理できないのか、私はまだ興味があります。前もって感謝します。

4

1 に答える 1

3

一般に、2 つのユーザー インターフェイス スレッドを持つことは、多くの場合悪い考えであり、完全に不要です。

通常、単一のユーザー インターフェイス スレッドを使用し、実際の計算作業をバックグラウンド スレッドに移動するだけです。ユーザー インターフェイスの更新は、必要に応じてメイン スレッドにマーシャリングされます。 BackgroundWorker多くの場合、これに最適です。

キャンセルに関しては、これは通常、と を中心に構築されたフレームワークの協調キャンセル モデルを使用して処理するのが最適です。これらは、複数のスレッドでの使用を念頭に置いて設計されており、必要な適切なメモリ バリアを自動的に処理します。CancellationTokenSourceCancellationToken

于 2013-05-02T15:50:05.423 に答える