0

AutoResetEventは、WaitOne()呼び出しの途中でメッセージループを完全にフリーズし(場合によっては)、シグナルメッセージを効果的にブロックすることに気づきました。

IE:

  1. (UI)新しいスレッドが生成されました
  2. (UI)コードはWaitOne();を呼び出します。タイムアウト:10秒
  3. (T2)スレッドがデバイスを開き、Set()を呼び出します
  4. (UI)WaitOneはメッセージループをブロックします
  5. (UI)WaitOneタイムアウトが経過し、コードの実行が続行されます
  6. (UI)メインウィンドウは信号を受信して​​続行します(ただし、WaitOneは失敗しました)

何か案は?

編集:スレッドを指定するためのUI/T2を追加しました。また、サードパーティのライブラリを同期にしようとしています。デバイスを開くには、OpenOKまたはOpenFailedイベントを生成するOpen()呼び出しが含まれます。生成されたイベントに応じて、true / falseを返すboolOpen()呼び出しを作成しようとしています。

4

3 に答える 3

1

...効果的に信号メッセージをブロックします。

「シグナルをブロック」して送信されることはできません。他のスレッドがイベントを設定するポイントに到達するのを防ぐことしかできません。待機ハンドルには、メッセージ ポンプはまったく必要ありません。

私が考えることができる唯一のことは、問題の COM オブジェクトが UI スレッドに関連付けられていることです。COM オブジェクトへのアクセスは、T2 が何かをするのを待っている UI スレッドに T2 から戻ろうとしている可能性があります (デッドロック)。これが実際に問題であるかどうかを確認するには、UI スレッドで COM オブジェクトを作成またはアクセスしていないことを確認してください。

于 2009-09-29T02:41:33.860 に答える
0

これは競合状態の結果です。問題は、ステップ 3 がステップ 2 の前に発生している可能性があることです。これは、それらが異なるスレッド上にあるためです。AutoResetEvent を使用しているため、WaitOne が呼び出されるまでに、イベントは既にリセットされています。

この問題のため、私は通常、可能な限り AutoResetEvents を避け、ManualResetEvents を優先するようにしています。

ManualResetEvent を使用したイベントの順序は次のようになります (イベント 2 を 2a および 2b としてリストし、操作の順序が保証されていないことを示しています)。

  1. 新しいスレッドが生成されました
  2. を。元のスレッドが WaitOne() を呼び出します。b. 新しいスレッドは Set(); を呼び出します。
  3. 元のスレッドが起きます。
  4. 元のスレッドが Reset(); を呼び出します。
于 2009-09-28T23:52:57.087 に答える
0

「処理を続行しながらメインスレッドで待機中」に関するこの
SO投稿を見つけることができる場合があります。

于 2009-09-29T01:19:52.123 に答える