使用async/await:await 返回得太早

3

我有一个简单的Windows Forms应用程序,上面只有一个按钮和一个进度条。

然后我有以下代码:

private async void buttonStart_Click(object sender, EventArgs e)
{
    progressBar.Minimum = 0;
    progressBar.Maximum = 5;
    progressBar.Step = 1;
    progressBar.Value = 0;

    await ConvertFiles();
    MessageBox.Show("ok");
}

private async Task ConvertFiles()
{
    await Task.Run(() => 
    {
        for (int i = 1; i <= 5; i++)
        {
            System.Threading.Thread.Sleep(1000);
            Invoke(new Action(() => progressBar.PerformStep()));
        }
    });
}
await ConvertFiles(); 返回得太早了,当进度条显示约80%时就已经弹出“确定”对话框了。
我做错了什么?

如果您同步运行此代码,进度条是否能正常工作? - Alex
你肯定会想要用 await Task.Delay 替换你的 Sleep。 - spender
我可以重现这个问题。我也尝试了 progressBar.Value = i。可能是 ProgressBar 的实现在更新 UI 时存在一些延迟吗?我检查了源代码,它使用的是同步的 SendMessage 方法... 这是一个非常有趣的问题。 - René Vogt
@RenéVogt 遇到类似的问题,我不得不增加/减少/增加当前值。Ollie应该尝试并查看这个解决方法是否会产生所需的结果。 - Alex
@Alex:你的意思是progressBar.Value++,然后progressBar.Value--,再然后progressBar.Value++吗?这样做没有帮助。 - Oliver Kötter
2个回答

6

你是对的。这会有所帮助:Invoke(new Action(() => { progressBar.Maximum = 101; progressBar.Value = 101; progressBar.Maximum = 100; progressBar.Value = 100; })); - Oliver Kötter

0

为了安全起见,为什么不移动

MessageBox.Show("ok");

将其转换为ContinueWith:

            await ConvertFiles().ContinueWith((t) => { MessageBox.Show("ok"); });

这可以确保任务完成时才运行


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接