2014-12-13 24 views
19
public async Task<string> GetName(int id) 
    { 
     Task<string> nameTask = 
      Task.Factory.StartNew(() => { return string.Format("Name matching id {0} = Developer", id); }); 
     return nameTask.Result; 
    } 

Nella dichiarazione di ritorno metodo sopra Sto usando la proprietà Task.Result.Qual è la differenza tra attendere l'attività <T> e l'attività <T>. Risposta?

public async Task<string> GetName(int id) 
    { 
     Task<string> nameTask = 
      Task.Factory.StartNew(() => { return string.Format("Name matching id {0} = Developer", id); }); 
     return await nameTask; 
    } 

Qui sto usando Attendere attività. Non sbaglio se penso che l'attesa rilascerà il thread chiamante ma Task.Result lo bloccherà, sarebbe giusto?

+1

Poiché il secondo codice non ha seguito, non ottieni nulla. nel primo codice contrassegni semplicemente il metodo async ma non ti aspetti. –

+0

Per saperne di più su async-await dare un'occhiata agli articoli su [my 'async-await'curation] (http://curah.microsoft.com/45553/asyncawait-general). –

+0

@RoyiNamir, la tua affermazione non è corretta? Il primo metodo non guadagna nulla usando 'async' poiché il metodo blocca il thread chiamante. Tuttavia, il secondo metodo dovrebbe fornire il thread corrente e non il blocco fino a quando l'attività non viene impostata in uno stato di completamento. –

risposta

24

Non ho torto se penso che l'attesa rilascerà il thread chiamante ma Task.Result lo bloccherà, sarebbe giusto?

In generale, sì. await task; "renderà" il thread corrente. task.Result bloccherà il thread corrente. await è un'attesa asincrona; Result è un'attesa di blocco.

C'è un'altra differenza più piccola: se l'attività viene completata in uno stato di errore (cioè, con un'eccezione), quindi await sarà (ri) sollevare tale eccezione così com'è, ma Result sarà avvolgere l'eccezione in AggregateException.

Come nota a margine, evitare Task.Factory.StartNew. Non è quasi mai il metodo corretto da usare. Se devi eseguire il lavoro su un thread in background, preferisci Task.Run.

Entrambi Result e StartNew sono appropriati se si sta eseguendo dynamic task parallelism; altrimenti, dovrebbero essere evitati. Né è appropriato se si sta facendo asynchronous programming.

+0

Grazie Stephen Cleary e Yuval Itzchakov per ulteriori informazioni su questo. –

4

Non mi sbaglio se penso che l'attesa rilascerà il thread chiamante ma Task.Result lo bloccherà, sarebbe giusto?

Sei corretto, a patto che l'attività non sia stata completata in modo sincrono. In caso affermativo, l'utilizzo di Task.Result o await task verrà eseguito in modo sincrono, in quanto await verificherà innanzitutto se l'attività è stata completata. In caso contrario, se l'attività non è stata completata, bloccherà il thread chiamante per Task.Result, mentre l'utilizzo di await sarà a in modo sincrono attendere per il completamento delle attività. Un'altra cosa che differisce è la gestione delle eccezioni. Mentre il primo propagherà un AggregationException (che può contenere una o più eccezioni), quest'ultimo lo scartoffierà e restituirà l'eccezione sottostante.

Come nota a margine, using asynchronous wrappers over sync methods is bad practice and should be avoided. Inoltre, l'utilizzo di Task.Result all'interno di un metodo asincrono è causa di deadlock e deve essere evitato.

Problemi correlati