我嘗試使用async/await調用運行某個操作時更新進度條,但UI正在更新時凍結。當進度條得到更新時,UI被阻塞
基本上這是一個非常簡單的需求,當使用BackgroundWorker時,但現在使用這個async/await調用事情似乎變得有點複雜。
首先,async/await的用法可以像BackgroundWorker一樣填充進度條嗎?這兩種方法有什麼共同點?
在我的用戶界面我有一個進度條和一個按鈕,當點擊按鈕時,進度條開始更新,但UI凍結,這應該不會發生,因爲async/await應該以「併發」方式工作。 如果我使用BackgroundWorked來完成此操作,UI不會凍結。
有人可以請我解釋一下我做錯了什麼,以及如何修改下面的代碼,以便在進度條更新時保持UI響應? 當更新進度條時,async/await的用法可以像BackgroundWorker那樣工作嗎?
下面是我的代碼:
private async void button1_Click(object sender, EventArgs e)
{
await CallMethodAsync();
}
private async Task CallMethodAsync()
{
this.progressBar1.Value = 0;
this.progressBar1.Maximum = 1000000;
var progressbar1 = new Progress<double>();
progressbar1.ProgressChanged += Progressbar1_ProgressChanged;
await ExecuteMethodAsync(progressbar1);
}
private async Task ExecuteMethodAsync(IProgress<double> progress = null)
{
await Task.Run(new Action(() => {
double percentComplete = 0;
bool done = false;
while (!done)
{
if (progress != null)
{
progress.Report(percentComplete);
}
percentComplete += 1;
if (percentComplete == 1000000)
{
done = true;
}
}
}));
}
private void Progressbar1_ProgressChanged(object sender, double e)
{
this.progressBar1.Increment(1);
}
不要等待更新欄的任務,並使用'this.Invoke(new Action()....'來更新UI。 – Crowcoder
Ignore @ Crowcoder的評論。您的代碼沒問題。等待並使用'Progress 「'實際上是這種情況的現代成語,你的代碼中的問題是你沒有做任何實際的工作,你只是用更新發送UI線程,並且它跟不上。例如,將迭代計數改爲100而不是1000000,並在你的while循環中添加一個await Task.Delay(500);你不但可以擺脫await Task.Run( )'(即循環可以在你的'ExecuteMethodAsync()'方法中,而不是lambda),它會像你想要的那樣工作。 –