2014-01-24 6 views
5

ich einen kleinen Service haben, die ein Bild hochgeladen hat, und ich benutze es dies wie:Fortschritt nur dann, wenn ein Task-Dialogfeld angezeigt nicht in der angegebenen Zeit beendet haben

ImageInfo result = await service.UploadAsync(imagePath); 

Was ich tun möchte anzuzeigen ein Fortschrittsdialog, aber nur, wenn der Upload-Vorgang mehr als beispielsweise 2 Sekunden dauert. Nachdem der Upload abgeschlossen ist, möchte ich den Fortschrittsdialog schließen.

Ich machte eine grobe Lösung mit Task/ContinueWith, aber ich hoffte auf eine "elegantere" Art und Weise.

Wie erreiche ich dies mit async/await?

+0

Suchen Sie nach einem modalen oder nicht modalen Dialog? WPF oder WinForms? – Noseratio

+0

@Noseratio es ist nicht der Dialog Ich hatte (hatte) das Problem mit, es ist die richtige Menge an Magie, um es ohne hässliche Rückruf-Suppe zu zeigen :) –

Antwort

3

Kann so etwas sein?

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

Sehr ähnlich zu dem, was ich getan habe! Vielen Dank! –

+0

Sriram und @IgalTabachnik, ich bin immer noch cuorios, wenn 'ShowMyProgress' hier einen modalen oder nicht modalen Dialog anzeigt. – Noseratio

+0

@Noseratio war ein nicht-modaler Dialog, gezeigt mit '.Show()'. –

3

dachte, ich würde immer noch meine Lösung veröffentlichen, da es zeigt, wie ein modal Dialog zu zeigen und zu entlassen. Es ist für WPF, aber das gleiche Konzept gilt für 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 
    } 
} 
Verwandte Themen