Obecnie próbuję zrobić fragment kodunapisany w VS 2012, przy użyciu Microsoft.Bcl.Async i .NET 4.0, działa w VS 2010. Dla VS 2010 zainstalowałem Async CTP (wersja 3), tak że mogę skompilować mój projekt napisany w V S2012 .
Po wielu problemach z uruchomieniem pakietu Async CTP mogę teraz skompilować mój projekt zarówno pod VS 2012, jak i VS 2010.
Jednak widzę pewne różnice w sposobie działania kodu w czasie wykonywania. Kod, który wykonuję, pokazano poniżej:
public class Fetcher
{
public string RunTask()
{
Task<string> task = TaskEx.Run(() => RunTaskAsync());
return task.Result;
}
public async Task<string> RunTaskAsync()
{
await TaskEx.Delay(1);
return "Hello";
}
}
Zasadniczo to, co mam, to metoda asynchroniczna, do której muszę mieć wrapper synchronizacji, tak aby klienci mogli wywoływać asynchroniczną lub synchronizowaną wersję metody.
Problem: Podczas uruchamiania kodu z VS 2012 obie metodyzwróci wynik „Hello”, a co ważniejsze, obie metody zostaną poprawnie zamknięte. Jednak uruchomienie kodu z VS 2010 to zupełnie inna historia. Metoda asynchroniczna działa zgodnie z przeznaczeniem, ale metoda opakowywania synchronicznego po prostu zawiesza się, a wynik nie jest nigdy generowany.
Ponieważ jestem całkiem nowy w koncepcji TPL iasync / wait, mam pewne problemy z wyjaśnieniem zachowania, które tu widzę. Czy istnieją jakieś ograniczenia w Async CTP, które się włączają, o których nie wiem, czy też robię to w niewłaściwy sposób?
Odpowiedzi:
4 dla odpowiedzi № 1Z reguły, Odradza się stosowanie synchronicznych opakowań wokół metod asynchronicznych. Kiedy używasz Result
podejdź, ty ryzykować impasem (jak opisuję na moim blogu); również, Result
zawinie wszelkie wyjątki, dzięki czemu obsługa błędów będzie trudniejsza.
Więc powiedziałem „nie rób tego”.
Jeśli chodzi o Async CTP, istnieje wiele błędów, o których wiadomo, że istnieją (plus kilka innych, które nie są publiczne). I nie zostaną naprawione silnie zalecamy uaktualnienie wszystkich do VS2012.
W tym konkretnym przypadku może to być związane z wydajnością. Na przykład., Task.Delay(1)
zwraca zadanie, które zostanie ukończone niemal natychmiast, więc między początkiem opóźnienia a await
który sprawdza, czy zadanie jest już zakończone. Więc możliwe jest, że poprawa wydajności w oficjalnym Microsoft.Bcl.Async
powodują różnicę w zachowaniu.