Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Displaying progress dialog only if a task did not finish in specified time

I have a little service that uploads an image, and I use it like this:

ImageInfo result = await service.UploadAsync(imagePath);

What I'd like to do is to display a progress dialog, but only if the upload operation takes more than, say, 2 seconds. After the upload is done, I want to close the progress dialog.

I made a crude solution using Task/ContinueWith, but I was hoping for a more "elegant" way.

How can I achieve this using async/await?

like image 753
Igal Tabachnik Avatar asked Jan 24 '14 10:01

Igal Tabachnik


2 Answers

May be something like this?

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();
}
like image 74
Sriram Sakthivel Avatar answered Sep 28 '22 08:09

Sriram Sakthivel


Thought I'd still post my solution, as it illustrates how to show and dismiss a modal dialog. It's for WPF, yet the same concept applies to 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
    }
}
like image 25
noseratio Avatar answered Sep 28 '22 08:09

noseratio