幾年前,您必須創建一個BackgroundWorker對象來完成這項工作,以保持UI的響應。
由於幾年來我們有異步的等待可以完成這項工作。異步等待函數看起來像同步代碼,但每當看到等待時,代碼就會停止,直到它正在等待的任務完成。與此同時,等待的線程有時間做其他事情,比如更新進度條或保持UI響應。一旦線程正在等待的任務完成後,線程會在等待之後繼續執行語句。
要使用async-await,唯一要做的就是聲明事件處理程序異步。完成之後,您可以調用其他異步函數並等待其結果。
開始進程後,您可以等待Task.Delay(TimeSpan)。在這個方法中,主線程沒有做任何事情,所以有時間去做其他UI的東西。延遲完成後,它可以更新進度條並查看過程是否完成。
using System.Diagnostics;
private async void pictureBox1_Click(object sender, EventArgs e)
{
// start the progress, don't wait until finished yet:
var process1 = Process.Start("c:/installer.exe").WaitForExit();
while (!process1.HasExited)
{
// process not finished yet, increase progress bar and wait a while
this.progressBar1.Step();
await Task.Delay(TimeSpan.FromSeconds(0.2);
}
// if here, process1 has finished: we are halfway:
progressBar1.Value = (progressbar1.Minimum + progressBar1.Maximum)/2;
// start process 2
var process2 = Process.Start("c:/installer2.exe");
while (!process2.HasExited)
{
// process not finished yet, increase progress bar and wait a while
this.progressBar1.Step();
await Task.Delay(TimeSpan.FromSeconds(0.2);
}
// both processes finished; full progressbar:
this.progressBar1.Value = this.progressBar1.Maximum;
}
當然,您可能會遇到安裝需要很長時間的問題。如果值變得太高,請考慮不再更新進度條
var halfWay = (progressbar1.Minimum + progressBar1.Maximum)/2;
while (!process1.HasExited)
{
if (this.progressBar1.Value < halfWay)
this.progressBar1.Step();
...
}
請注意,異步等待由一個線程完成。它不是多任務處理。 Eric Lippert在計算器上有一個很好的比喻: async/await - Is this understanding correct?
假設你必須做早餐。吐司麪包,煮一些雞蛋。
- 同步:開始烘烤麪包。等到烘烤完成。開始煮雞蛋,等到雞蛋煮熟。
- 異步但不併發:開始烤麪包,而麪包烘烤開始煮雞蛋。當雞蛋烹飪時,你可以做其他事情,比如做茶。過了一段時間後,等到雞蛋煮熟後,等待麪包烘烤。這通常是異步等待。
- 異步併發:僱用一名廚師烤麪包,僱傭一名廚師煮雞蛋,等到兩名廚師完成。這裏的烘烤和烹飪是由不同的線程完成的。這是最昂貴的方法
這是C#代碼。你確定你正在編寫C++/CLI嗎? – nvoigt