【问题标题】:Displaying progress dialog only if a task did not finish in specified time仅当任务未在指定时间内完成时才显示进度对话框
【发布时间】:2014-01-24 10:23:49
【问题描述】:

我有一个上传图片的小服务,我像这样使用它:

ImageInfo result = await service.UploadAsync(imagePath);

我想做的是显示一个进度对话框,但前提是上传操作需要超过 2 秒。上传完成后,我想关闭进度对话框。

我使用 Task/ContinueWith 做了一个粗略的解决方案,但我希望有一个更“优雅”的方式。

如何使用async/await 实现这一目标?

【问题讨论】:

  • 您在寻找模式对话框还是非模式对话框? WPF 还是 WinForms?
  • @Noseratio 这不是我有(有)问题的对话框,它是正确数量的魔法让它在没有丑陋的回调汤的情况下显示:)

标签: c# .net task-parallel-library async-await


【解决方案1】:

可能是这样的?

var uploadTask = service.UploadAsync(imagePath);
var delayTask = Task.Delay(1000);//Your delay here
if (await Task.WhenAny(new[] { uploadTask, delayTask }) == delayTask)
{
    //Timed out ShowProgress
    ShowMyProgress();
    await uploadTask;//Wait until upload completes
    //Hide progress
    HideProgress();
}

【讨论】:

  • 与我最终做的非常相似!谢谢!
  • Sriram 和 @IgalTabachnik,如果 ShowMyProgress 在这里显示模态或非模态对话框,我仍然很高兴。
  • @IgalTabachnik,您是否同意在操作进行时用户仍然可以访问主窗口 UI,因为对话框是无模式的?
  • @Noseratio 如果它是模态对话框,那么这个逻辑将被打破:(感谢您的编辑,这是一个错字
【解决方案2】:

我想我还是会发布我的解决方案,因为它说明了如何显示和关闭 modal 对话框。它适用于 WPF,但同样的概念也适用于 WinForms。

private async void OpenCommand_Executed(object sCommand, ExecutedRoutedEventArgs eCommand)
{
    // start the worker task
    var workerTask = Task.Run(() => {
        // the work takes at least 5s
        Thread.Sleep(5000);
    });

    // start timer task
    var timerTask = Task.Delay(2000);
    var task = await Task.WhenAny(workerTask, timerTask);

    if (task == timerTask)
    {
        // create the dialog
        var dialogWindow = CreateDialog();

        // go modal
        var modalityTcs = new TaskCompletionSource<bool>();

        dialogWindow.Loaded += (s, e) =>
            modalityTcs.SetResult(true);

        var dialogTask = Dispatcher.InvokeAsync(() =>
            dialogWindow.ShowDialog());

        await modalityTcs.Task;

        // we are now on the modal dialog Dispatcher frame
        // the main window UI has been disabled

        // now await the worker task
        await workerTask;

        // worker task completed, close the dialog
        dialogWindow.Close();
        await dialogTask;

        // we're back to the main Dispatcher frame of the UI thread
    }
}

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 2017-09-02
    • 2013-01-04
    • 1970-01-01
    • 2019-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多