我有我的類中有一些內部循環的方法。 這個方法的主要目的是轉換一些文件,所以我在我的表單中放置了一個進度條,在每個文件轉換後應該更新。C#BackgroundWorker ProgressChanged不會被觸發,直到函數結束
我嘗試了所有可能的組合,並且閱讀了所有可能的內容,但無法解決此問題。
void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
converterProgressBar.Value = e.ProgressPercentage;
}
僅在我的方法的主循環執行後才被調用。
這是我的方法:
public string Convert()
{
convertBtn.Enabled = false;
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
totalCount = files.length;
bw.RunWorkerAsync();
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
foreach (string file in files)
{
countFile++;
if (chk.Checked)
{
class1.DoJob();
}
using (// some code))
{
using (//some other code))
{
try
{
using (// again some code)
{
// job executing
}
}
catch (exception
{
}
}
}
convertedVideosL.Text = txtToUpdate;
convertedVideosL.Refresh();
}
countFile = countFile + 1;
MessageBox.Show("Done");
countFile = -1;
return outputFile;
}
這裏是BackgroundWorker
事件處理程序:
void bw_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= totalCount; i++)
{
if (bw.CancellationPending)
{
e.Cancel = true;
}
else
{
int progress = Convert.ToInt32(i * 100/totalCount);
(sender as BackgroundWorker).ReportProgress(progress, i);
}
}
}
void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
converterProgressBar.Value = e.ProgressPercentage;
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled == false)
{
convertedVideosL.Text = "Finished!";
}
else
{
convertedVideosL.Text = "Operation has been cancelled!";
}
}
但我無法得到更新每一個轉換文件中的進度條。 它等待foreach循環結束,然後調用bw_ProgressChanged
。
如果我把RunWorkerAsync()
放在foreach循環中,會引發一個異常,說明BackgroundWorker
忙,不能執行其他任務。
在我看來,很明顯,DoWork()
只執行一個for循環,然後它不應該是知道的轉換正在進行,但ProgressChanged
應該由ReportProgress(progress,i)
被解僱的。
可以請某人解釋我的原因並幫助我解決問題嗎?
謝謝!
根據您發佈的代碼,我認爲您對BackgroundWorker存在誤解。該工作應該發生在BackgroundWorker內部(即將邏輯從Convert轉換爲bw_DoWork)。在循環的每次迭代(在DoWork!內部)觸發ReportProgress方法。 – syazdani
你能否詳細說明一下?因爲我試圖運行DoWork中的代碼,但是如何在循環之後觸發ReportProgress方法?我在哪裏放RunWorkerAsync? –
有很多事情,你需要改變,以使其工作。您應該在bw_DoWork中運行Convert方法,但不應該訪問內部控件(如chk,convertedVideosL),也不應該使用MessageBox-es。你應該從那裏調用bw.ReportProgress並在bw_ProgressChanged中處理它,你可以在這裏更新你的UI。坦率地說,使用'async/await'完成所有這些工作會容易得多,你有這個選擇嗎? –