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