Отображение диалогового окна хода выполнения, только если задача не была завершена в указанное время

У меня есть небольшой сервис, который загружает изображение, и я использую его так:

ImageInfo result = await service.UploadAsync(imagePath);

Что я хотел бы сделать, это отобразить диалоговое окно прогресса, но только если операция загрузки занимает, скажем, более 2 секунд. После завершения загрузки я хочу закрыть диалог прогресса.

Я сделал грубое решение, используя Task/ContinueWith, но я надеялся на более "элегантный" способ.

Как я могу добиться этого с помощью async/await?

2 ответа

Решение

Может быть как то так?

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();
}

Думаю, я все еще опубликую свое решение, так как оно показывает, как показывать и закрывать модальный диалог Это для 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
    }
}
Другие вопросы по тегам