2014-04-25 10 views
22

In uno dei video MVA ho visto prossima costruzione:Come attendono sulla asincrona delegato

static void Main(string[] args) 
{ 
    Action testAction = async() => 
    { 
     Console.WriteLine("In"); 
     await Task.Delay(100); 
     Console.WriteLine("First delay"); 
     await Task.Delay(100); 
     Console.WriteLine("Second delay"); 
    }; 
    testAction.Invoke(); 
} 

risultato dell'esecuzione sarà:

In 
Press any key to continue . . . 

E 'perfettamente compila, ma in questo momento non mi vedere qualsiasi modo per attendere. Potrei mettere Thread.Sleep o Console.ReadKey dopo l'invocazione, ma non è quello che voglio.

Così come questo delegato dovrebbe essere modificato per diventare awaitable? (O almeno come si può pista che l'esecuzione completato?)

è che ci sono alcun uso pratico di tali delegati?

+4

Non c'è modo per 'await' esso. Se fosse 'Func ', sarebbe diverso. Ecco perché 'async void' dovrebbe essere evitato e preferibilmente utilizzato nei gestori di eventi di livello superiore * only *. –

+2

È possibile trovare [il mio post sul blog sui delegati 'async'] (http://blog.stephencleary.com/2014/02/synchronous-and-asynchronous-delegate.html) utile. –

risposta

39

Al fine di qualcosa per essere atteso, deve essere awaitable. Come void non è così, non è possibile attendere su alcun delegato Action.

Un awaitable è un qualsiasi tipo che implementa un metodo GetAwaiter, che restituisce un tipo che implementa sia INotifyCompletion o ICriticalNotifyCompletion, come Task e Task<T>, per esempio.

Se si vuole aspettare un delegato, utilizzare Func<Task>, che è l'equivalente di un metodo chiamato con la seguente firma:

public Task Func() 

Così, al fine di attendere, cambiare il metodo di:

static void Main(string[] args) 
{ 
    Func<Task> testFunc = async() => 
    { 
     Console.WriteLine("In"); 
     await Task.Delay(100); 
     Console.WriteLine("First delay"); 
     await Task.Delay(100); 
     Console.WriteLine("Second delay"); 
    }; 
} 

E ora si può attendere che:

await testFunc(); 
Problemi correlati