2013-03-28 39 views
5

Próbuję użyć async i oczekuję poleceń w formularzu z VS2012 framework 4.5. Moja metoda asynchroniczna SlowMethodAsync niczego nie zwraca. Uwaga: ten kod działa poprawnie w aplikacji konsoli.Dlaczego otrzymuję WaitingforActivation TaskStatus

private void button1_Click(object sender, EventArgs e) 
{ 
    var task = SlowMethodAsync(); 

    for (int i = 0; i < 10; i++) 
    { 
     Console.WriteLine(i); 
    } 

    System.Threading.Tasks.TaskStatus status = task.Status; 

    Console.WriteLine("Slow method result on Thread: {0}", task.Result); //This line never executes 
    Console.WriteLine("Main complete on {0}", Thread.CurrentThread.ManagedThreadId); 
} 

//Why is this method not returning anything? 

static async Task<int> SlowMethodAsync() 
{ 
    Console.WriteLine("Slow method started on Thread: {0}", Thread.CurrentThread.ManagedThreadId); 

    await Task.Delay(2000); 

    Console.WriteLine("Slow method complete on Thread: {0}", Thread.CurrentThread.ManagedThreadId); 

    return 42; 
} 

Odpowiedz

5

Spowodowałeś zakleszczenie.

Użycie blokuje wątek interfejsu użytkownika - nie można zakończyć, dopóki nie zostanie zakończone zadanie zwrócone przez SlowMethodAsync.

Jednak ponieważ SlowMethodAsync został zwodowany w kontekście synchronizacji również na wątku UI, kontynuacji po awaitrównież chce wykonać na wątku UI.

Tak Result nie można ukończyć, dopóki metoda asynchroniczna nie zostanie zakończona ... a metoda asynchroniczna nie może się zakończyć, dopóki nie zakończy się Result.

Zamiast tego, należy dokonać metodą button1_Click asynchroniczny zbyt, a następnie użyć:

Console.WriteLine("Slow method result on Thread: {0}", await task); 

Powodem tego będzie pracował w app konsoli było to, że metoda SlowMethodAsync nie miałby żadnego konkretnego kontekstu synchronizacji wracać do, aby kontynuacja mogła zostać wykonana na dowolnym wątku puli wątków - który nie byłby blokowany przez "główny" wątek oczekujący na zadanie.

+0

Solidna odpowiedź, jak zwykle. Pracowałem w wielu zespołach, w których większość programistów nie rozumiała kontekstu, w którym wykonywali ich wątki (co częściej powodowało wyjątki podczas próby aktualizacji elementów UI z kontekstu synchronizacji poza trybem UI). Sądzę, że stanowi to wadę dokumentacji API, która czyni pewne zastrzeżenia dla programistów, którzy nie posiadają wiedzy na temat koncepcji systemów operacyjnych/programowania równoległego (jedna z podstawowych grup, którą ten sprytny API próbuje obsłużyć). Masz pomysł, jak społeczność może temu zaradzić? – marr75

+2

@ marr75: W WinForms UIs jest * ogromna * ilość dokumentacji wokół wątków. Podobnie jest z wieloma informacjami na temat metod asynchronicznych, chociaż jest to zdecydowanie bardziej zaawansowany temat. Problemem nie jest brak dokumentacji, IMO - to brak ludzi * czytanie * dokumentacji. –

+0

Wow to działało :) Jestem nowy w frameworku 4.5. Dzięki za pomoc – user2221178

Powiązane problemy