【问题标题】:Using async/await: await returns too early使用 async/await:await 返回太早
【发布时间】:2016-04-12 02:23:01
【问题描述】:

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

然后我有这个代码:

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(); 返回太早,ok 消息框已经出现在大约 80% 的进度。

我做错了什么?

【问题讨论】:

  • 如果同步运行这段代码,进度条能正常工作吗?
  • 你肯定想把你的睡眠换成await Task.Delay
  • 我可以重现。我也试过progressBar.Value = iProgressBar 的实现是否有可能在更新 ui 时有一些延迟?我检查了来源,它使用 SendMessage 应该是同步的....非常有趣的问题。
  • @RenéVogt 遇到类似问题,我不得不增加/减少/增加当前值。 Ollie 应该尝试看看这种解决方法是否会产生预期的结果。
  • @Alex:你的意思是progressBar.Value++,然后是progressBar.Value--,然后又是progressBar.Value++?没有帮助。

标签: c# winforms asynchronous async-await progress-bar


【解决方案1】:

为了安全为什么不移动

MessageBox.Show("ok");

进入一个Continuewith so:

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

这确保它只在任务完成时运行

【讨论】:

    【解决方案2】:

    您遇到的问题与您正确使用的async/await 无关。 await 没有返回太早,只是进度条更新太晚了。换句话说,这是在多个线程中描述的进度条控制特定问题 - Disabling .NET progressbar animation when changing value?Disable WinForms ProgressBar animationThe RunWorkerCompleted is triggered before the progressbar reaches 100% 等。您可以使用这些线程中提供的解决方法之一。

    【讨论】:

    • 你是对的。这有帮助: Invoke(new Action(() => { progressBar.Maximum = 101; progressBar.Value = 101; progressBar.Maximum = 100; progressBar.Value = 100; }));
    猜你喜欢
    • 1970-01-01
    • 2018-10-11
    • 2018-04-13
    • 2012-01-11
    • 2019-10-12
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    • 2019-10-08
    相关资源
    最近更新 更多