我需要能夠連續運行我的BackgroundWorker
。 DoWork
事件包含一個線程池並且OnComplete
更新我的UI。連續運行BackgroundWorker
我一直沒有找到一種方法來無限循環BackgroundWorker.RunWorkerAsync()
方法,而不是整個程序凍結。任何幫助將不勝感激。
我需要能夠連續運行我的BackgroundWorker
。 DoWork
事件包含一個線程池並且OnComplete
更新我的UI。連續運行BackgroundWorker
我一直沒有找到一種方法來無限循環BackgroundWorker.RunWorkerAsync()
方法,而不是整個程序凍結。任何幫助將不勝感激。
你必須在你的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");
}
}
而不是'while(true)'use'((BackgroundWorker)sender).CancellationPending',你支持取消。 – CodeZombie
我用你的零件更新了我的代碼 – Tomtom
雖然邏輯需要翻轉。 CancellationPending最初是錯誤的,當用戶想要取消它時會變爲true。所以循環應該檢查'!worker.CancellationPending' – Chris
如果你的程序被凍結,這可能是因爲你的無限循環的背景工作者線程在旋轉,使用100%的CPU。你沒有說過爲什麼你需要它在無限循環中運行,但是你可以先在該循環中放置一個Thread.Sleep
。
Thread.Sleep是不好的做法,不應該投入生產。這個問題似乎是一些其他的while循環,比如while(true)。當運行一個長時間運行的任務,然後結束時,應該使用線程。即使任務完成,也沒有理由保持線程運行。你需要讓事情「自然地發生」,正如他們所說的那樣。 –
@Ahmedilyas - 我不建議把任何東西投入生產。我認爲運行無限循環的BackgroundWorker是一個值得懷疑的做法,但放入Thread.Sleep可能會讓OP超出「應用程序凍結」問題,並且變得更加關注他的設計。他沒有說過爲什麼他想要一個無限循環,所以很難提出哪些替代方案可能更合適。 – Joe
請注意,'無限循環'並不意味着100%的CPU使用,一般來說,在多線程應用程序中 - 通常,它們會阻塞某些東西。此外,Thread.Sleep的使用確實是不好的做法,但它有合法的用途。 –
我在過去需要某些東西在後臺運行時已經這樣做了。 如果您嘗試在運行背景工作時運行,您將會得到一個幫助! 這就是爲什麼當完成事件完成時,我使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.
}
而不是隻是開始它的時間完成,爲什麼不只是有一段時間(真)循環,所以它無限運行? – bkribbs
完美無瑕地工作!它的實現比定時器更容易,不需要鎖定用戶界面就可以完成工作!非常感謝,偉大的方法:)!應該標記爲答案。 –
--bkribs因爲這樣你也可以在「ProgressUpdated」和「WorkerCompleted」中添加代碼,如果你需要更新UI元素:) –
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
{
}
}
總是一個好主意,包括一些形式的細節或描述,爲什麼你的答案工作,而不是隻是碼。 –
儘管此代碼片段可能會解決問題,但[包括解釋](// meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers)確實有助於提高帖子的質量。請記住,您將來會爲讀者回答問題,而這些人可能不知道您的代碼建議的原因。也請儘量不要使用解釋性註釋來擠佔代碼,因爲這會降低代碼和解釋的可讀性! – FrankerZ
你要什麼你'BackgroundWorker'辦?你爲什麼要它連續運行? –
爲什麼不直接使用「常規」螺紋呢?或者可能是任務或其他。爲什麼你需要BackgroundWorker? AFAIK它並不意味着要這樣使用,永遠。 – walther
您可以與主線程(UI)進行通信,並使BackgroundWorker與ReportsProgress一起運行。 – Paparazzi