2012-12-04 21 views
11

mam tę prostą metodę:Zadanie <T> kontra Asynchroniczni delegaci w C#?

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

mogę uruchomić go z:

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

Albo z tym:

Func<string, int> method = Work; 
IAsyncResult myIasync= method.BeginInvoke ("lalala", null, null); 
... 
int result = method.EndInvoke (myIasync); 
  • Obie używają wątku puli wątków.
  • Oba czekają na wykonanie, aby zakończyć (podczas odczytywania wartości)
  • Oba wyrzucą każdy wyjątek do osoby dzwoniącej.

Kiedy należy używać każdego?

+0

Zakładam, że zadanie jest lepsze, ponieważ jest nowsze, ale nie wierzę, że będzie jakakolwiek różnica w stosunku do tego małego kodu. –

Odpowiedz

18

Drugi formularz, używając IAsyncResult, jest znacznie starszy i znacznie mniej wydajny. Task<T> został wprowadzony w .NET 4 i jest obecnie preferowanym sposobem reprezentowania operacji asynchronicznych. Jest znacznie prostszy w użyciu, szczególnie w języku C# 5, który obsługuje "funkcje asynchroniczne", w których można oczekiwać na zadanie (lub inną operację asynchroniczną) w sposób nieblokujący.

zamiast wywoływania BeginInvoke prawdopodobnie nie zmieni zbyt wiele o tym, jak sama operacja jest wykonywana (chociaż daje więcej opcji w zakresie planowania itp.), Ale robi ogromną różnicę z perspektywy kodu który chce "obejrzeć" operację, użyć wyników, czekać na wiele zadań, obsługiwać awarie itp.

Jeśli możesz ewentualnie użyć C# 5 (albo z .NET 4.5, albo z .NET 4 plus pakiet docelowy asynchroniczny) znacznie uprości to twoje życie, jeśli chodzi o zarządzanie operacjami asynchronicznymi. To jest droga naprzód :)

+0

Dzięki. Powiedzmy, że wykonanie zadania zajmuje bardzo dużo czasu. Czy wiąże on wątek wątku, dopóki się nie skończy (więc teraz wątek ma wątki [n-1])? lub praca jest delegowana do wątku non-threadpool i dopiero po zakończeniu wraca do wątku z wątkami ...? –

+1

@ AutoExec.Bat: Jeśli użyjesz 'Task', możesz powiedzieć, że jest to długotrwałe zadanie, w którym to przypadku użyłoby wątku nie wątku. Nie jest jasne, co masz na myśli, mówiąc "wraca do wątku z wątkami". Czy * co * wraca do wątku puli wątków? –

+0

Należy wykonać zadanie. to długa praca. to zadanie może zostać wykonane z wątkiem threadpool, ** lub ** może zostać przeniesione do wątku ** non-threadpool ** (więc teraz wątek jest _back_ do puli - do serwera innych żądań), a kiedy zadanie zostało zakończone (w wątku bez wątków) - sygnalizuje: _ "hej, skończyłem pracę" _, a sterowanie powróciło do wątku wątku. (chodzi o to, aby nie tracić wątków Threadpool). Moje pytanie brzmi: w jaki sposób _Task vs IAsync_ działa w ten sposób ... (czy rzeczywista praca jest zwariowana przez wątek threadpool lub nonthreadpool?) –

0

Zadanie jest bardziej eleganckie i zostało wprowadzone niedawno (.Net 4), więc jeśli spełni twoje oczekiwania, pójdę z tym.