我想更好地了解如何从异步操作更新Windows窗体进度栏,但我得到了一些意外的行为。从异步方法更新进度栏
基本上我正在点击一个按钮来更新进度条,然后在进度条100%更新后将其设回0。
这是我的代码:
private async void button1_Click(object sender, EventArgs e)
{
await CallMethodAsync().ContinueWith((prevTask) =>
{
prevTask.Wait();
progressBar1.Invoke(new Action(() => { progressBar1.Value = 0; }));
});
}
private static async Task ExecuteMethodAsync(IProgress<double> progress = null)
{
double percentComplete = 0;
bool done = false;
while (!done)
{
if (progress != null)
{
progress.Report(percentComplete);
}
percentComplete += 10;
if(percentComplete == 100)
{
done = true;
}
}
}
private async Task CallMethodAsync()
{
var progress = new Progress<double>();
progress.ProgressChanged += (sender, args) => { progressBar1.Increment(10); };
await ExecuteMethodAsync(progress);
}
有了这个实施进度条并不是在所有的,即使我把更新的“等待()”上应该更新进度条的值的操作。
如果我删除这部分代码:
progressBar1.Invoke(new Action(() => { progressBar1.Value = 0; }));
进度条被更新,但它仍然是所有的时间这样的,我想将其设置回0,一旦它被完全充满,这样我当我再次点击按钮时,可以再次更新它。
有人可以请解释我做错了什么?
你应该得到一个编译器警告*“CS1998 C#这个异步方法缺少'await'操作符,并且会同步运行,考虑使用'await'操作符来等待非阻塞API调用或'await Task.Run(.. )'在后台线程上执行CPU绑定的工作。“*。你做错的事情是导致编译器警告,并且警告甚至会告诉你如何解决它。 –
此外,你不应该混合[ContinueWith和异步](https://blog.stephencleary.com/2013/10/continuewith-is-dangerous-too.html)(但这不会导致你的问题) –
检出https ://stackoverflow.com/questions/11500563/winform-multithreading-use-backgroundworker-or-not –