[英]Form freezing using BackgroundWorker
我正在使用WinForm,從中我需要的所有進程都被引導。 現在我正在嘗試將BackgroundWorker
與ProgressBar
和取消按鈕集成到我的代碼中。 我希望它在我的代碼本地,而不是在一個單獨的方法。 要對此進行測試,將創建一個帶有進度條(尚未激活)的新表單和一個用於停止for循環的按鈕。 但是,代碼無法正常工作(甚至還沒有包含進度條)。 表格立即凍結(見圖)所以我無法測試取消按鈕。 然而,執行for循環並顯示"Done: " + l.ToString()
。 我怎么解決這個問題?
void stopMeasurement(object sender, EventArgs e)
{
stopMeas = true;
}
public void testcancel() // Test method which is triggered manually
{
int l = 0;
MetingProgress metingProgress = new MetingProgress();
metingProgress.btnCancelmeting.Click += new EventHandler(stopMeasurement);
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerSupportsCancellation = true;
worker.DoWork += (sender, args) =>
{
for (int k = 0; k < 10; k++)
{
Thread.Sleep(1000);
l++;
if (worker.CancellationPending)
break;
}
MessageBox.Show("Done: " + l.ToString());
};
worker.RunWorkerAsync();
while (worker.IsBusy)
{
if (stopMeas)
worker.CancelAsync();
}
metingProgress.Dispose();
MessageBox.Show("All done");
}
這段代碼是你的問題:
while (worker.IsBusy)
{
if (stopMeas)
worker.CancelAsync();
}
你的GUI-Thread就在那個循環中,直到你的工作完成。 您需要從EventHandler中訪問您的worker實例,並從那里調用worker.CancelAsync()。
除此之外,我個人會分兩步改進代碼:
將整個BackgroundWorker移動到MetingProgress類中,並使其構造函數為實際工作實現提供委托。
使用TAP(任務異步模式),即async / await Task with Progress和CancellationToken。
表格立即凍結
這是因為你有一個while循環仍在主線程上運行! 因此表單不會響應。 這叫做buisy等待。 您將無法調用CancelAsync
方法。
一種解決方案可能是刪除while循環並將取消調用放入按鈕事件代碼中:
void stopMeasurement(object sender, EventArgs e)
{
stopMeas = true;
worker.CancelAsync();
}
你基本上做的是:你創建了第二個取消令牌。 所以另一種可能性是只使用stopMeas
來取消后台操作:
worker.DoWork += (sender, args) =>
{
for (int k = 0; k < 10; k++)
{
Thread.Sleep(1000);
l++;
if (stopMeas)
break;
}
string mes = stopMeas ? "Done: " + l.ToString() : "Task aborted!";
MessageBox.Show(mes);
};
編輯:這一行:
metingProgress.Dispose();
可能會導致ObjectDisposed異常。 如果后台進程仍在運行並嘗試更新進度條,則您已經處理了該表單。 您應該刪除此行並將其留給垃圾收集器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.