Mam niektóre kodu, który tworzy zadanie, które wykonuje jakąś powolną pracę tak:Jak utworzyć zadanie, które oczekuje czekać wewnątrz ciała, które zachowuje się tak samo jak wersja synchroniczna, gdy jest wywoływana funkcja Czekaj?
public static Task wait1()
{
return new Task(() =>
{
Console.WriteLine("Waiting...");
Thread.Sleep(10000);
Console.WriteLine("Done!");
});
}
w rzeczywistych realizacji, Thread.Sleep rzeczywiście będzie wezwanie serwis internetowy. Chciałbym zmienić ciało metody można użyć czekać (więc nie zużywają wątku podczas dostępu do sieci/uśpienia). Moja pierwsza próba (oparta na debugowaniu przez debugowanie błędów kompilacji) była następująca:
public static Task wait2()
{
return new Task(async() =>
{
Console.WriteLine("Waiting...");
await Task.Delay(10000);
Console.WriteLine("Done!");
});
}
Jednak; to zadanie nie wydaje się zachowywać tak samo jak pierwsze, ponieważ kiedy wywołuję na nim funkcję .Wait(); wraca natychmiast.
Poniżej znajduje się pełna próbka (aplikacja konsolowa) pokazująca różnice (aplikacja zakończy się natychmiast po uruchomieniu drugiego zadania).
Co muszę zrobić, abym mógł zadzwonić Start i czekać na Zadanie, które zdarzyło się, że ma kod z wyczekiwaniem w środku? Zadania są kolejkowane i wykonywane później przez agenta, dlatego ważne jest, aby zadanie nie zostało uruchomione automatycznie.
class Program
{
static void Main(string[] args)
{
var w1 = wait1();
w1.Start();
w1.Wait(); // This waits 110 seconds
var w2 = wait2();
w2.Start();
w2.Wait(); // This returns immediately
}
public static Task wait1()
{
return new Task(() =>
{
Console.WriteLine("Waiting...");
Thread.Sleep(10000);
Console.WriteLine("Done!");
});
}
public static Task wait2()
{
return new Task(async() =>
{
Console.WriteLine("Waiting...");
await Task.Delay(10000);
Console.WriteLine("Done!");
});
}
}
Po co robić "nowe zadanie" w ogóle? Dlaczego nie uczynić zewnętrznej metody 'async' i czy automatycznie zwróci' Task'? Oznacza to, że 'static async Task wait3() {Console.WriteLine (" ... "); poczekaj na Task.Delay (10000); Console.WriteLine ("..."); } ' –
@EricLippert Próbowałem tego; ale wygląda na to, że zachowuje się inaczej ... Wywołanie '.Start()' wyrzuca 'System.InvalidOperationException: Start może nie zostać wywołany w zadaniu stylu obietnicy.". Moje zadania idą do kolejki, którą później można nazwać; więc muszę móc je później uruchomić. –
Czy Twoim celem jest zatrzymanie wait1/2 na linii oczekującej do momentu, gdy zostanie wywołany Start? Pytam to na podstawie twojego komentarza do @cucaesta, że "muszę mieć możliwość zadzwonienia do Startu później". Jeśli tak jest, myślę, że pytanie wymaga aktualizacji wraz z wykonaniem, na które masz nadzieję. –