2009-04-19 13 views
1

Webページのインデックス作成プログラムを動作させるのに問題があります。データベースサーバーからインデックスするURLを自動的にダウンロードし、インデックス付きページ情報を含む応答をUDP経由で返信するフォームがあります。私は、着信および発信メッセージを追跡するUDPと呼ばれる静的クラスを持っています。メッセージが受信されるたびに起動するイベントがあります。このフォームは、URLデータベースを保持するサーバー上のプログラムから送信されたメッセージを追跡するためのすべてのインデックスコードフックを含みます。作成されたスレッドとは別のスレッドから呼び出されるイベントハンドラを取得するにはどうすればよいですか?

インデックス作成フォームの前に表示される別のフォームを追加するまで、これは問題なく機能していました。これで、インデックスフォームが別のスレッド(Application.Run()と2番目のスレッド)で開きます。問題は、イベントが発生したときにイベントハンドラが呼び出されなくなることです。

問題は、ここで何が起こっているのか、それを修正するために何ができるのでしょうか?イベントが発生したスレッドハンドラ以外のスレッドでイベントハンドラを呼び出さないクロススレッドセーフティメカニズムが必要であることは確かです。誰かがこれを行う別の方法やこれを回避する方法を知っていますか?事前に感謝...

答えて

3

UIコントロールは、作成されたスレッド(UIスレッド)で操作する必要があります。 これを達成するには、イベントハンドラを「呼び出す」必要があります。

EventHandler handler = myEventHandler; 
if(handler != null) 
{ 
    ISynchronizeInvoke target = handler.Target as ISynchronizeInvoke; 

    if(target != null && target.InvokeRequired) 
    { 
     target.Invoke (handler, ...); 
    } 
    else 
    { 
     handler.DynamicInvoke (...); 
    } 
} 

それとも、あなたもAsyncOperation & AsyncOperationManagerクラスを見てすることができます

これは次のようにイベントを発生させることによって行うことができます。

また、もっと簡単な場合は、SynchronizationContextクラスをご覧ください。このクラスの 'Current'プロパティを使用すると、イベントハンドラを囲むSendOrPostCallbackデリゲートを投稿することができます。

+0

ここでDynamicInvokeを使用する必要は通常ありません。* target *がこれを行うのがより一般的です... –

0

私はこれが「安全機構」ではないと思います。デバッガに入っていて、適切なもの以外のスレッドからUIにアクセスしようとすると、がWinForms(.NET 2.0以降)に存在する安全機構によって例外がスローされます。

でイベントが呼び出されていないことを確認してください。?それは非常に奇妙に聞こえる。デバッガのイベントハンドラにブレークポイントを置くと、そのブレークポイントはヒットしませんか?

しかし、別の方法で質問に答えるには、イベントハンドラ全体を特定のスレッドで実行させることはありません。複数のハンドラが登録されていて、それらのハンドラが異なるスレッドで実行する必要がある場合があります。代わりに、私はイベントハンドラ自体をスレッドセーフなものにします - 特定のスレッドで何らかのアクションを実行する必要がある場合、それらはスレッドにマーシャリングします(例えばControl.BeginInvokeなどで)。

あなたのネットワークアクセスのほとんどはどのスレッドで行われますか?私はそれがではないことを願っています。のUIスレッドが含まれていることを願っています(そうでないと、応答しないUIが発生する可能性があります)。それは前に働いていたら、おそらくすでに適切なマーシャリングをしているということです...非常に奇妙です。

これが役に立たない場合、問題を示す短くて完全なプログラムを考え出すことができますか?具体的なコードを診断する方が簡単です。

関連する問題