2013-11-04 15 views
12

私は継続的に私のBackgroundWorkerを実行する必要があります。 DoWorkイベントにはプールスレッドプロセスが含まれ、OnCompleteにはUIが更新されます。バックグラウンドワーカーを継続的に実行

プログラム全体がフリーズすることなく、BackgroundWorker.RunWorkerAsync()メソッドを無限ループする方法を見つけることができませんでした。どんな助けでも大歓迎です。

+1

あなたはあなたの 'BackgroundWorker'をどうするかをしたいですか?なぜあなたはそれを継続的に実行したいのですか? –

+1

「通常の」スレッドを使用するだけではどうですか?それとも、タスクや何か..なぜあなたはBackgroundWorkerが必要ですか? AFAIKこれは、これほどまでに使用されることは意図されていませんでした。 – walther

+1

プライマリスレッド(UI)に通信して、ReportsProgressを使用してBackgroundWorkerを実行し続けることができます。 – Paparazzi

答えて

23

DoWorkメソッドでループを作成する必要があります。 UIを更新するには、ProgressChanged-Methodを使用します。ここで小さな例では、これはあなたのプログラムが凍結されている場合、それはあなたの無限ループバックグラウンドワーカースレッドがCPUを100%使用して、回転しているためかもしれ

public Test() 
    { 
     this.InitializeComponent(); 
     BackgroundWorker backgroundWorker = new BackgroundWorker 
      { 
       WorkerReportsProgress = true, 
       WorkerSupportsCancellation = true 
      }; 
     backgroundWorker.DoWork += BackgroundWorkerOnDoWork; 
     backgroundWorker.ProgressChanged += BackgroundWorkerOnProgressChanged; 
    } 

    private void BackgroundWorkerOnProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     object userObject = e.UserState; 
     int percentage = e.ProgressPercentage; 
    } 

    private void BackgroundWorkerOnDoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = (BackgroundWorker) sender; 
     while (!worker.CancellationPending) 
     { 
      //Do your stuff here 
      worker.ReportProgress(0, "AN OBJECT TO PASS TO THE UI-THREAD"); 
     }   
    } 
+5

'while(true)'の代わりに '((BackgroundWorker)sender).CancellationPending'を使用し、取り消しをサポートします。 – CodeZombie

+0

私のコードはあなたの部品で更新されます – Tomtom

+1

ロジックはそれを反転させる必要があります。 CancellationPendingは最初はfalseで、ユーザーがキャンセルしたいときにtrueになります。ループが '!worker.CancellationPending'をチェックしているはずです – Chris

-2

のように見えることができる方法です。あなたは無限ループで実行する必要がある理由については言いませんでしたが、最初にThread.Sleepをループに入れることができます。

+1

Thread.Sleepは実践的であり、生産のために入れてはいけません。おそらくwhile(真)のようなループが進行している間、問題は他のものと思われます。長時間実行しているタスクを実行して終了するときは、スレッドを使用する必要があります。タスクが終了してもスレッドを実行させ続ける理由はありません。彼らが言うように、あなたは物事が「自然に起こる」ようにする必要があります。 –

+0

@Ahmedilyas - 私はプロダクションに何かを入れることを勧めませんでした。私は、無限ループを実行しているBackgroundWorkerは疑わしい習慣だと考えていますが、Thread.Sleepを配置すると、OPが「アプリケーションフリーズ」の問題を超えて、デザインに関する詳細を考える立場に入る可能性があります。彼はなぜ無限ループを望んでいるのか言っていないので、どのような選択肢がより適切かもしれないかを示唆することは難しい。 – Joe

+0

「無限ループ」は、マルチスレッドのアプリケーションでは一般的に100%のCPU使用を意味するものではないことに注意してください。通常は、何かをブロックします。また、Thread.Sleepのこの使用法は実際に悪い習慣ですが、正当な使用法があります。 –

4

私は過去に何かをバックグラウンドで実行する必要があるときこれをしました。 実行中にバックグラウンドワーカーを実行しようとすると、あなたは腹を立てるでしょう! これは、完了したイベントでBackGroundWorkerが起動したときに、BackGroundWorkerを起動させる理由です。

そして、それは永遠にループします。

private void Main_Load(object sender, EventArgs e) 
{ 
    // Start Background Worker on load 
    bgWorker.RunWorkerAsync(); 
} 

private void bgWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    Thread.Sleep(1000); // If you need to make a pause between runs 
    // Do work here 
} 

private void bgCheck_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
// Update UI 

// Run again 
bgWorker.RunWorkerAsync(); // This will make the BgWorker run again, and never runs before it is completed. 
} 
+1

これまでに終了したばかりの時間ではなく、ちょうどwhile(true)ループで無限に動作するのはなぜですか? – bkribbs

+2

完璧に機能しました!その実装はタイマーよりも簡単で、UIをロックすることなくその仕事をしました!ありがとう、素晴らしい方法:)!答えとしてマークする必要があります。 –

+0

--bkribsこのように、UI要素を更新する必要がある場合は、 "ProgressUpdated"と "WorkerCompleted"でコードを追加することもできます:) –

-1
timer.interval=60000 // 1 min 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     timer1.Start(); 

    } 
private void timer1_Tick(object sender, EventArgs e) 
    { 
     try 
     { 
      //Do something 
     } 
     catch 
     { 


     } 
    } 
+0

答えがちょうどではなく、コード。 –

+1

このコードスニペットは質問を解決するかもしれませんが、[説明を含めて](// meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers)本当にあなたの投稿の質を向上させるのに役立ちます。将来読者の質問に答えていることを覚えておいてください。そうした人々はあなたのコード提案の理由を知らないかもしれません。また、コードと説明の両方の可読性が低下するため、説明的なコメントを使用してコードを混乱させないようにしてください。 – FrankerZ

関連する問題