2009-08-14 4 views
0

私のアプリケーションでは、ときどきバックグラウンドスレッドをいくつか実行します。メインスレッドは、インターフェイスを更新するバックグラウンドスレッドを待っています

これは、メインウィンドウの進行状況バーも更新します。これはInvokeを呼び出してメインスレッドにインターフェイスを更新させることで行います。

ユーザーがアプリケーションを終了すると、フォームを閉じる前にすべてのバックグラウンドスレッドが終了するまで待つ必要があります。フォーム終了イベントで私は何かがあります

  while (this._Queue.Count > 0) 
      Application.DoEvents(); 

しかし、これは動作しません!

Invoke呼び出しでバックグラウンドスレッドが停止しています。メインスレッドは、そのDoEventを呼び出すことを繰り返しています。私はそれを呼び出して呼び出しを処理するために必要だったと思います。しかし、これはそうではありません...

どうして!

+1

こんにちは、 はどこにメインフォームを閉じるイベントにこのコードを入れたのですか? よろしくご協力ありがとうございます。 Iordan – IordanTanev

+0

はい、これはメインフォームのform_closingイベントです。 –

答えて

0

そうですね、私は別の角度から取り上げて問題を分類しました。スレッドが終了するのを待つ必要はもうありません...

私は変数bool KillOnThreadFinishをワーカースレッドに追加しました。

次に、メインフォームのフォームを閉じて、スレッドが実行中かどうかを確認します。私がKillOnThreadFinish = trueを設定している場合は、e.cancel = true(その時点でフォームが閉じないように)を設定し、MainForm.Enabled = falseを設定します(ユーザーがフォームを再び閉じないようにします)。

スレッドが作業を終了すると、KillOnThreadFinishがチェックされ、TrueがApplication.Exit()を呼び出してアプリケーションが終了する場合。

美しく動作するようです!

(しようとみんなに感謝します。:-))

0

フォームの「終了」イベントにコードを挿入することをおすすめします。また、Application.DoEvents()の後にThread.Sleep(100)を追加することもできます。スレッドが開始され、それが働いて行われている指示にスレッドによって設定される前に

また、私は(イベントのコンストラクタにtrueを渡す)起動時に設定されているthreadDoneまたは類似呼ばManualResetEventを作成し、リセットされますと思います。

while (!threadDone.WaitOne(100, true)) 
{ 
    Application.DoEvents(); 
    Thread.Sleep(100); 
} 

これは役立つかもしれない - しかし、私は実際に今、この権利を試していないが、次のように

次に、あなたのループを書き換えることができます。私が通常行っているのは、リセットイベントを使って、アプリケーションやフォームを閉じることができるかどうかをチェックすることです。スレッドが完了していない場合は、ユーザーにメッセージを表示します。

1

BackgroundWorkerは、バックグラウンドスレッドを実行する便利な方法を提供しますが、.NETイベントを使用して進行状況を簡単にレポートすることができます。 ProgressBar UIアップデートをProgressChangedイベントハンドラに接続すると、完了はRunWorkerCompletedを通してあなたに報告されます。バックグラウンドスレッドが1つしかない場合は、独自のスレッド処理コードをローリングするよりもはるかに簡単です。ここでは、MSDNの記事です:

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

あなたが定期的にスレッドを使用して立ち往生している場合は、私が完了するまでスレッドを待つ参加使用して検討したいです。これにより、通常のメッセージの処理が継続され、ポーリングがタイトなループに保存されます。ここではより多くの情報があります。また

http://msdn.microsoft.com/en-us/library/95hbf2ta.aspx

は、タイムアウトパラメータ(ミリ秒のInt32またはTimeSpanオブジェクトのいずれか)を取るオーバーロードがあります。この時間が経過してもスレッドが完了していない場合、例外がスローされます。これは、シャットダウンしようとしている間に突っついているスレッドを捕らえるのに役立ちます。もっとここに:

http://msdn.microsoft.com/en-us/library/6b1kkss0.aspx

私はこのことができます願っています。

+0

Join doesntは動作しているように見えますが、Joinのメインスレッドがデッドロック状態になり、InvokeにWorkerスレッドがスタックしてしまいます。 –

0

メインスレッドは他のスレッドを待つべきではなく、他のスレッドがその作業が完了したことを通知する必要があります。

私の場合、別のスレッドのControl.InvokeまたはControl.BeginInvokeメソッドを使用してUIを更新するだけです。

+0

私は動作していません。 –

+0

メインスレッドは何かを待ってブロックしてはいけません。何もしないでください。同時に、他のスレッドはそれを完了し、メインスレッドに通知します。 –