2013-01-31 5 views
5

Mam przenośną bibliotekę klas (PCL) skierowaną do Profile158 (Windows Store, .NET 4.5, Silverlight 5, Windows Phone 8). Mogę łatwo pracować z metodami, które zwracają typ zadania, i wszystko działa tak, jak bym się spodziewał. Za każdym razem, gdy uzyskuję dostęp do właściwości Result, kończy się ona asynchronicznym kodem i zwraca wynik.Używanie Microsoft.bcl.async w PCL z Mono Droid?

Jednak jeśli użyję asynchronicznych/oczekujących słów kluczowych w metodzie wewnątrz PCL, otrzymam zadanie z powrotem. Jednak gdy próbuję uzyskać dostęp do właściwości Wynik, blokuje ona i nigdy nie zwraca.

Patrząc w okno wyjściowe debugowania w Visual Studio w obu przypadkach widzę ten sam tekst:

Thread started: 
Thread started: 
Loaded assembly: Mono.Security.dll [External] 
Thread started: 
Thread started: 

Wygląda więc na to, jakby kod zostanie uruchomiony, ale nigdy nie powraca do wątku UI. Czy ktoś próbował użyć PCL z Microsoft.bcl.async w PCL?

Mój projekt Mono Droid jest przeznaczony dla systemu Android 2.1.

Dzięki, - John

Aktualizacja:
Oto kilka dodatkowych informacji na temat różnych scenariuszy. Po pierwsze, tutaj jest kod, który działa na Mono Droid kiedy napisany w kodzie Ui:

var task = request.GetResponseAsync(); 
string html = task.Result.GetResponseText(); 

Następnie tworzone następujące metody w PCL:

public async Task<string> Test() 
{ 
    IHttpResponse responce = await GetResponseAsync(); 
    return responce.GetResponseText(); 
} 

i nazwać ten kod z mono kod UI:

string html = request.Test().Result; 

nigdy nie powróci ...

+0

W przypadku użycia właściwości Wynik, która będzie blokowana do momentu zakończenia zadania. Jeśli robisz to z tego samego wątku, w którym samo zadanie musi wykonać, w zasadzie dałeś sobie impas. Nie jest jasne, co teraz robi twój kod ... czy masz krótki, ale kompletny program demonstrujący problem? –

+0

@dsplaisted używał tej warstwy z MonoDroid podczas swojej demonstracji w BUILD - http://channel9.msdn.com/Events/Build/2012/3-004 - Dodam tag PCL do tego postu i wypuszczę sygnał nietoperza - będzie on towarzyszył podczas godzin pracy w Redmond ... – Stuart

+0

Nie związane z twoim pytaniem, ale Microsoft.Bcl.Async nadal jest w wersji beta. Używając go w dowolnym kodzie produkcyjnym należy unikać. Oczywiście, możesz po prostu testować to teraz. –

Odpowiedz

3

to classic deadlock scenario, A s opisuję na moim blogu.

Domyślnie await przechwytuje "kontekst" i używa go do wznowienia metody async. Ten "kontekst" to bieżący numer SynchronizationContext, chyba że jest to null, w którym to przypadku jest to bieżący numer TaskScheduler.

Wywołujesz metodę async z wątku interfejsu użytkownika (który zapewnia SynchronizationContext), a następnie blokujesz wątek interfejsu użytkownika, wywołując Result. Metoda async nie może zostać zakończona, ponieważ próbuje zakończyć wątek interfejsu użytkownika, który jest zablokowany.

Aby rozwiązać ten problem, należy przestrzegać następujących zasad:

  1. Zastosowanie async całą drogę w dół. Nie wywołuj linii Result ani Wait w przypadku metod zwracanych z Task; zamiast tego użyj await.
  2. Użyj kodu ConfigureAwait(false), jeśli to możliwe.

Pomocne może być również moje async/await intro.

+0

Mam OK z blokowaniem kodu interfejsu, dopóki operacja nie zostanie zakończona. Problem polega na tym, że nigdy się nie kończy i nigdy nie wraca do wątku UI. Jeśli zwrócę zadanie z mojej metody i nie używam async/await, kod UI blokuje się na krótko, a następnie zwraca. Próbowałem dokładnie tego samego kodu interfejsu użytkownika w aplikacjach Windows Phone 8 i Windows Store, a oba zwracają się poprawnie do wątku interfejsu użytkownika. Sprawdziłem również, czy synchronizacja nie jest pusta w systemie Android, a nie jest. Jest więc coś na temat Androida i PCL, które używają asynchronizacji/oczekiwania, które wydają się być przyczyną problemu. –

+0

Ten sam zakleszczenie występuje we wszystkich UI, w tym WP8 i netcore. Jeśli masz kod, który używa 'Result' na metodzie' async' w WP8 bez zakleszczenia i tego samego * zakleszczenia * dokładnego * kodu w Androidzie, to proszę opublikuj kod. –

+0

Właśnie napisałem kod. –