2012-03-15 19 views
1

私はいくつかのプロジェクトでプログラムを作成していますが、いくつかのプロジェクトはログを記録するためにメインプロジェクトメッセージに戻って報告します。C#:内部動作:イベント、Control.BeginInvokeおよびプログラム終了=割り込み?

私はAsynchソケットを使用しているので、これらのメッセージのいくつかは別のスレッドに戻ってくるので、メインスレッドに着くとInvokeRequiredをチェックし、trueならthis.BeginInvokeを使ってロギングを処理します。

サーバーの場合は特にUIスレッドで処理する必要があります。ここでは、ListBoxで最後にログに記録されたメッセージを表示するので、テスト中に操作の進行状況を確認できます。

いくつかのメッセージが切り替わる可能性があることは時々わかりますが、今のところ私はそれで生きることができます。何らかの理由でBeginInvokeの代わりにInvokeを使用すると、クライアントが接続されている間にサーバーを停止するとクラッシュし、例外も発生しません。しかし、私はBeginInvokeを使用してこれを克服しました。

私の質問は、プログラムの終了時にイベントとBeginInvokeがどのように機能するかを理解することです。イベントがキューに入っている場合、またはBeginInvokeがプログラムの終了直前に呼び出された場合は、即座に終了し、すべてを取り消しますか?私の場合、保留中のメッセージをログに記録して終了するか、すべての保留中のアクションを実行しますか?

+0

フォームが破棄されると、呼び出しキューがフラッシュされるため、残りの操作(ログ)は実行されません。これは問題を解決するものではありません。呼び出しがもう発生しないことが確実になるまで、フォームを閉じることを許可することはできません。たとえば、ソケットを最初に閉じます。 –

+0

私は最初にソケットを閉じます - それは私のログイベントが発生したときです - ソケットが閉じられたことを記録する - 私の質問は、プログラムが閉じられる前にログが常に処理されるか、まだ待ち行列に入っていないか、またはbegininvokeがまだ行われていません。ソケットの廃棄には関係ありません。 – 537mfb

+0

フォームが破棄されると、呼び出しキューがフラッシュされます。実行中ではなく、保留中の呼び出しを削除する*。 –

答えて

2

すべてのBeginInvokedデリゲートが確実に実行されるようにするには、フォームを閉じるのを延期する必要があります。実際にフォームを閉じるキューに別のBeginInvokeデリゲートを追加して2段階のプロセスにすることで、これを行うことができます。このように:

+0

ありがとう - 多くの感謝ハンス - 素晴らしい解決策 - あなたはfalseに閉じて初期化してはいけませんか? – 537mfb

+0

あなたのコードに1つの修正 - base.OnFormClosing(e);内部でなければならないif文 - 外部でない - そうでないとスタック外例外が発生する – 537mfb

0

BeginInvokeを呼び出してUIを更新すると、コードはスレッドプールからのスレッドによって実行されます。また、コードが例外を発生させると、アプリケーション全体ではなくスレッドのみが終了します。あなたのプログラムがクラッシュしていないのを見たのはこのためです。

BeginInvokeが呼び出されたばかりで、プログラムがすぐに終了したとき。スレッドプールからのスレッド

+0

BeginInvoke(ノンブロッキング)ではなくInvoke(ブロッキング)を使用するとプログラムがクラッシュしました。 – 537mfb

関連する問題