2013-02-02 19 views
40

Jestem nowy w programowaniu asynchronicznym, więc po przejściu przez kilka przykładowych kodów asynchroniczny, myślałem o pisaniu prosty kod asynchronicznynie można niejawnie przekonwertować typu „ciąg” do „System.Threading.Tasks.Task <string>”

I stworzyłem prostą aplikację Winform i wewnątrz formularza napisałem poniższy kod. Ale jej po prostu nie działa

private Task<string> methodAsync() { 
    Thread.Sleep(10000); 
    return "Hello"; //Error: Cannot implicitly convert type 'string' to 'System.Threading.Tasks.Task<string>' 
} 

private async void button1_Click(object sender, EventArgs e) 
{ 
    string s = await methodAsync(); 
    MessageBox.Show(s); 
} 

Może ktoś proszę umieścić trochę światła tutaj ..

Odpowiedz

68

Podana zwracany typ metody jest Task<string>. Próbujesz zwrócić wartość string. Nie są one takie same, ani nie ma niejawnej konwersji z ciągu znaków na Task<string>, stąd błąd.

Najprawdopodobniej myli to z async sposobu, w którym wartość zwracana jest automatycznie zawinięte w Task przez kompilator. Obecnie ta metoda nie jest metodą asynchroniczną. Prawie na pewno chcesz to zrobić:

private async Task<string> methodAsync() 
{ 
    await Task.Delay(10000); 
    return "Hello"; 
} 

Istnieją dwie kluczowe zmiany. Po pierwsze, metoda jest oznaczana jako async, co oznacza, że ​​typ zwracany jest zawijany w Task, co powoduje kompilację metody. Następnie nie chcemy czekać na blokowanie. Zasadą jest, że podczas korzystania z modelu await należy zawsze unikać blokowania, gdy tylko jest to możliwe. Task.Delay to zadanie, które zostanie ukończone po określonej liczbie milisekund. Przez await - w tym zadaniu skutecznie wykonujemy nieblokujące oczekiwanie na ten czas (w rzeczywistości pozostała część metody jest kontynuacją tego zadania).

Jeśli wolisz 4.0 sposób to zrobić bez użycia await, można to zrobić:

private Task<string> methodAsync() 
{ 
    return Task.Delay(10000) 
     .ContinueWith(t => "Hello"); 
} 

Pierwsza wersja zostanie skompilowany w dół do czegoś, co jest mniej więcej tak, ale będzie to miało niektóre dodatkowe kody w obsłudze wspomagającej obsługę błędów i inne funkcje await nie wykorzystujemy tutaj.

Jeśli Twój Thread.Sleep(10000) ma naprawdę być tylko zastępczym dla niektórych długo uruchomiony metody, a nie tylko sposobem czekając na chwilę, a następnie będziesz musiał upewnić się, że praca jest wykonywana w innym wątku, zamiast obecnego kontekstu. Najprostszym sposobem na osiągnięcie tego jest poprzez Task.Run:

private Task<string> methodAsync() 
{ 
    return Task.Run(()=> 
     { 
      SomeLongRunningMethod(); 
      return "Hello"; 
     }); 
} 

Albo raczej:

private Task<string> methodAsync() 
{ 
    return Task.Run(()=> 
     { 
      return SomeLongRunningMethodThatReturnsAString(); 
     }); 
} 
+1

jak mogę jednoznacznie owinąć 'string' w' Task'?LUB nie ma żadnego sposobu zwrócenia 'Task' lub' Task 'bez używania' async' i 'await' w wywołanej metodzie (w tym przypadku methodAsync)? – dotNETbeginner

+0

@dotNETbeginner no –

+1

@Aniket Nie, mylisz się, istnieje wiele sposobów na jawne zawijanie łańcucha znaków w zadaniu. Będę edytować rozwiązanie w. – Servy

12

Beyond problematycznego użycia async jak podkreślił @Servy, drugą kwestią jest to, że trzeba wyraźnie pobierz T z Task<T>, wywołując funkcję Task.Result. Zwróć uwagę, że właściwość Result blokuje kod asynchroniczny i powinna być używana ostrożnie.

Spróbuj:

private async void button1_Click(object sender, EventArgs e) 
{ 
    var s = await methodAsync(); 
    MessageBox.Show(s.Result); 
} 
+0

Chociaż nie jest to zalecane, wystąpił przypadek, w którym chciałem odzyskać zawartość 'Task ' w 'catch {}'. Nie mogłem "poczekać", a '.ToString()' wygenerował niepoprawne wyniki. To pasuje do rachunku. – doubleJ

13

Zastosowanie FromResult Metoda

public async Task<string> GetString() 
{ 
    System.Threading.Thread.Sleep(5000); 
    return await Task.FromResult("Hello"); 
} 
+1

dziękuję, że to jest dokładnie to, czego potrzebowałem, czego żadna z pozostałych odpowiedzi nie dostarczyła. –

+1

Najlepsza odpowiedź. Do momentu. – BaBu

+1

O ile mogę powiedzieć, że ta odpowiedź jest najlepszym sposobem wdrożenia interfejsu zdefiniowanego za pomocą zadania z implementacją synchroniczną –

Powiązane problemy