2

バックグラウンドスレッドで実行されるサードパーティのライブラリから発生したイベントがあります。このイベントは基本的に、ライブラリが監視しているシステムのステータス更新をリスナーに通知します。InvokeRequiredがtrueの場合、ハンドラーはUIスレッドでそれ自体を呼び出し、いずれの場合も、ステータス変更のエントリをテキストボックスのテキストに追加し、トレイに通知をポップアップします。

現在、問題は、これらのステータスの更新が非常に迅速に行われる可能性があることです。監視対象のシステムは、ミリ秒単位で「アイドル」状態からいくつかの中間体を経由して「準備完了」状態に移行できます。システムがこれらすべての中間状態を移行したことを知る必要があります。ただし、すべての状態変更がログに反映されるわけではありません。ブレークポイントを設定してハンドラーをステップスルーすると、最も奇妙な動作が示されます。ハンドラーはコードの最初の数行をステップスルーしてから、メソッドのエントリに戻ります。同じメソッドへの別の呼び出しが着信しているため、イベントまたはWindowsメッセージポンプのいずれかがメソッド呼び出しを中止しているように見えます。メソッド本体をロックブロックに入れても解決しません。

これは、このサードパーティライブラリを使用しない他のプロジェクトで以前に見たことがあります。連射イベントが単にウィンドウの再描画をトリガーしていたので、私はそこではそれほど心配していませんでした。それらがすべて起こった場合、素晴らしいですが、1つが短絡した場合、パイプ内に別の通過するものがありました。ただし、これはアプリケーションにとって非常に重要なタスクであり、イベントが発生するたびに順番に発生する必要があります(状態が実際に変化するほど速く発生する必要はありません。絶対にそれを予期していません)。

この短絡動作の原因は何ですか?また、どうすればそれを止めることができますか?

4

2 に答える 2

2

表示されているのは、最初にステップスルーを開始した呼び出しがまだ実行されている間に、バックグラウンドスレッドからイベントハンドラーへの新しい呼び出しである可能性があります。

于 2012-12-05T18:22:55.093 に答える
0

イベントハンドラーが起動するスレッドですべての作業を同期的に実行するのではなく、別のスレッドで作業を実行する方が有益な場合があります。

現在のイベントハンドラーで実行しているすべてをでラップするか、の代わりにUIスレッドにマーシャリングするためにTask.Factory.StartNew使用します。BeginInvokeInvoke

そのライブラリの知識がないため、確信が持てませんでしたが、前のイベントのすべてのイベントハンドラーの実行が完了するまで、それ以上のイベントを発生させることができない可能性があります。

この問題を解決するため、またはUIが非常に多くの更新に怒られるのを防ぐために、実行する必要のあるもう1つのオプションは、ステータスの変更を受け取ったときに取得し、それらをコレクションにダンプすることです。その収集を定期的にチェックし、すべての変更をバッチで処理するだけです。これは、コレクションにアイテムを追加するだけでよいため、サードパーティオブジェクトのイベントハンドラーで簡単になります。また、モニターができる時間内に数回更新する必要がないため、UIでも簡単になります。変更をレンダリングします。

于 2012-12-05T18:24:45.683 に答える