2013-11-04 153 views
12

我需要能夠連續運行我的BackgroundWorkerDoWork事件包含一個線程池並且OnComplete更新我的UI。連續運行BackgroundWorker

我一直沒有找到一種方法來無限循環BackgroundWorker.RunWorkerAsync()方法,而不是整個程序凍結。任何幫助將不勝感激。

+1

你要什麼你'BackgroundWorker'辦?你爲什麼要它連續運行? –

+1

爲什麼不直接使用「常規」螺紋呢?或者可能是任務或其他。爲什麼你需要BackgroundWorker? AFAIK它並不意味着要這樣使用,永遠。 – walther

+1

您可以與主線程(UI)進行通信,並使BackgroundWorker與ReportsProgress一起運行。 – Paparazzi

回答

23

你必須在你的DoWork-Method中做一個循環。要更新你的UI,你應該使用ProgressChanged-Method。這裏是一個小例子,這可怎麼看起來像

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)'use'((BackgroundWorker)sender).CancellationPending',你支持取消。 – CodeZombie

+0

我用你的零件更新了我的代碼 – Tomtom

+1

雖然邏輯需要翻轉。 CancellationPending最初是錯誤的,當用戶想要取消它時會變爲true。所以循環應該檢查'!worker.CancellationPending' – Chris

-2

如果你的程序被凍結,這可能是因爲你的無限循環的背景工作者線程在旋轉,使用100%的CPU。你沒有說過爲什麼你需要它在無限循環中運行,但是你可以先在該循環中放置一個Thread.Sleep

+1

Thread.Sleep是不好的做法,不應該投入生產。這個問題似乎是一些其他的while循環,比如while(true)。當運行一個長時間運行的任務,然後結束時,應該使用線程。即使任務完成,也沒有理由保持線程運行。你需要讓事情「自然地發生」,正如他們所說的那樣。 –

+0

@Ahmedilyas - 我不建議把任何東西投入生產。我認爲運行無限循環的BackgroundWorker是一個值得懷疑的做法,但放入Thread.Sleep可能會讓OP超出「應用程序凍結」問題,並且變得更加關注他的設計。他沒有說過爲什麼他想要一個無限循環,所以很難提出哪些替代方案可能更合適。 – Joe

+0

請注意,'無限循環'並不意味着100%的CPU使用,一般來說,在多線程應用程序中 - 通常,它們會阻塞某些東西。此外,Thread.Sleep的使用確實是不好的做法,但它有合法的用途。 –

4

我在過去需要某些東西在後臺運行時已經這樣做了。 如果您嘗試在運行背景工作時運行,您將會得到一個幫助! 這就是爲什麼當完成事件完成時,我使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

而不是隻是開始它的時間完成,爲什麼不只是有一段時間(真)循環,所以它無限運行? – bkribbs

+2

完美無瑕地工作!它的實現比定時器更容易,不需要鎖定用戶界面就可以完成工作!非常感謝,偉大的方法:)!應該標記爲答案。 –

+0

--bkribs因爲這樣你也可以在「ProgressUpdated」和「WorkerCompleted」中添加代碼,如果你需要更新UI元素:) –

-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