2012-12-04 10 views
11

ho questo metodo semplice:Compito <T> vs delegati asincroni in C#?

static int Work (string s) { return s.Length; } 

ho potuto correre con:

Task<string> task = Task.Factory.StartNew<int> (() => Work ("lalala")); 
... 
int result = task.Result; 

O con questo:

Func<string, int> method = Work; 
IAsyncResult myIasync= method.BeginInvoke ("lalala", null, null); 
... 
int result = method.EndInvoke (myIasync); 
  • entrambi utilizzano un filo di thread.
  • Entrambi attendono che l'esecuzione finisca (durante la lettura del valore)
  • Entrambi ripresentano qualsiasi eccezione al chiamante.

Quando dovrei usare ciascuno?

+0

Suppongo che l'attività sia migliore dal momento che è più recente, ma non credo che ci sarà alcuna differenza con questo piccolo codice. –

risposta

18

Il secondo modulo, che utilizza IAsyncResult, è significativamente più vecchio e molto meno potente. Task<T> è stato introdotto in .NET 4 ed è il modo preferito di rappresentare le operazioni asincrone ora. È molto più semplice da usare, in particolare in C# 5 che supporta "funzioni asincrone" in cui è possibile attendere un'attività (o un'altra operazione asincrona) in modo non bloccante.

L'utilizzo di Task invece di chiamare BeginInvoke probabilmente non cambierà molto su come viene eseguita l'operazione stessa (sebbene fornisca più opzioni in termini di pianificazione, ecc.), Ma fa un'enorme differenza dal punto di vista del codice che vuole "guardare" l'operazione, utilizzare i risultati, attendere più attività, gestire errori ecc.

Se è possibile utilizzare C# 5 (con .NET 4.5 o con .NET 4 più il pacchetto di targeting asincrono) renderà la tua vita notevolmente più semplice quando si tratta di gestire operazioni asincrone. È la via da seguire :)

+0

Grazie. Diciamo che il compito richiede molto tempo per essere eseguito. Lega un thread del threadpool fino a quando non termina (quindi ora il threadpool ha [n-1] thread)? o il lavoro è delegato a un thread non threadpool, e solo quando è finito, torna a un thread del threadpool ...? –

+1

@ AutoExec.Bat: se si utilizza 'Task', si può dire che si tratta di un'attività a esecuzione prolungata, nel qual caso utilizzerà un thread non threadpool. Non è chiaro cosa intendi con "si torna a un thread threadpool". * Cosa * torna a un thread thread-pool? –

+0

Un lavoro deve essere fatto. è un lavoro lungo questo lavoro può essere eseguito con un thread thread-thread, ** o ** può essere trasferito a un thread ** non-threadpool ** (quindi ora il thread è _back_ al pool - al server altre richieste), e quando il lavoro è terminato (nel thread non threadpool): segnala: _ "hey ho finito il lavoro" _ e il controllo ritorna a un thread del threadpool. (l'idea è di salvare i thread di threadpool da sprecare). Quindi la mia domanda è: come funziona _Task vs IAsync_ in quel modo ... (il vero lavoro è matto da un threadpool o thread nonthreadpool?) –

0

L'attività è più elegante ed è stata introdotta più di recente (.Net 4), quindi se soddisfa le tue esigenze, andrei con quello.