2010-10-27 7 views
26

Mam zadanie i oczekuję, że zajmie to mniej niż sekundę, ale jeśli trwa to dłużej niż kilka sekund, chcę anulować zadanie.Czy Task.Wait (int) zatrzymuje zadanie, jeśli upłynie limit czasu bez kończenia zadania?

Na przykład

Task t = new Task(() => 
     { 
      while (true) 
      { 
       Thread.Sleep(500); 
      } 
     }); 
t.Start(); 
t.Wait(3000); 

Należy zauważyć, że po 3000 milisekund upływa czas oczekiwania. Czy zadanie zostało anulowane, gdy upłynął limit czasu lub zadanie nadal działa?

+2

Dlaczego nie stosować api api? –

+0

Co to jest API anulowania? –

+0

sprawdź moją odpowiedź Zamieszczam kilka linków na ten temat –

Odpowiedz

12

Jeśli chcesz anulować Task, należy podać w a CancellationToken podczas tworzenia zadania. To pozwoli ci anulować Task z zewnątrz. Jeśli chcesz, możesz powiązać anulowanie z zegarem.

Aby utworzyć zadanie z tokenem anulowania zobaczyć ten przykład:

var tokenSource = new CancellationTokenSource(); 
var token = tokenSource.Token; 

var t = Task.Factory.StartNew(() => { 
    // do some work 
    if (token.IsCancellationRequested) { 
     // Clean up as needed here .... 
    } 
    token.ThrowIfCancellationRequested(); 
}, token); 

Aby anulować Task połączenia Cancel() na tokenSource.

+3

Czy to nie pozwala tylko na * żądanie * anulowania "z zewnątrz"? Czy delegat nie będzie zależał od tego, czy zwróci uwagę na żądanie oparte na tokenach, a faktycznie rzuci lub po prostu kontynuuje pracę bez anulowania? – BitMask777

+0

Prawidłowo, uczestnik decyduje, czy będzie działał na żądanie, zaznaczając "IsCancellationRequest" na właściwości. –

7

Zadanie jest nadal uruchomione, dopóki wyraźnie nie powiesz mu, aby zatrzymał się lub zakończyła się twoja pętla (co nigdy się nie stanie).

Można sprawdzić wartość zwracaną się doczekać, aby zobaczyć to:

(od http://msdn.microsoft.com/en-us/library/dd235606.aspx) Return Value

Typ: System.Boolean true jeśli Zadanie zakończono realizację w wyznaczonym czasie; w przeciwnym razie false.

5

Czy zadanie zostało anulowane, gdy upłynął limit czasu lub zadanie nadal działa?

Nie i tak.

Limit czasu przekazany do Task.Wait jest dla Wait, a nie zadaniem.

+0

To jest interesujące, ponieważ tekst pomocy tutaj wydaje się mówić coś odwrotnego: https://msdn.microsoft.com/en-us/library/dd270644(v=vs.110).aspx mówi, _ "Czeka, aż zadanie zakończy wykonywanie w ciągu określonej liczby milisekund "_ Nie jestem pewien, czy rozumiem to jeszcze. –

+0

@Michael Jeśli upłynie czas oczekiwania na 'Czekaj', nastąpi powrót, nawet jeśli zadanie nie zostało zakończone. W tym przypadku timeout zadanie będzie kontynuowane aż do jego zakończenia (a później 'Wait' zwróci się jako zakończony). – Richard

47

Task.Wait() czeka do określony czas na zakończenie zadania i zwraca, czy zadanie zostało wykonane w określonym czasie (lub wcześniej), czy też nie. Samo zadanie nie jest modyfikowane i nie polega na oczekiwaniu.

Czytaj ładna seria: Parallelism in .NET, Parallelism in .NET – Part 10, Cancellation in PLINQ and the Parallel class przez Reed Copsey

I: .NET 4 Cancellation Framework/Parallel Programming: Task Cancellation

Sprawdź następujący kod:

var cts = new CancellationTokenSource(); 

var newTask = Task.Factory.StartNew(state => 
          { 
           var token = (CancellationToken)state; 
           while (!token.IsCancellationRequested) 
           { 
           } 
           token.ThrowIfCancellationRequested(); 
          }, cts.Token, cts.Token); 


if (!newTask.Wait(3000, cts.Token)) cts.Cancel(); 
+0

Dzięki nicku to jest niesamowity kod –

+0

Cieszę się, że mogę Ci pomóc –

+0

Zauważyłem, że 'cts.Token' jest również przekazywany do metody' Wait() '. Znalazłem notatkę w dokumentacji Microsoftu: _ "Przekazanie obiektu cancellationToken do tej metody pozwala po prostu na anulowanie oczekiwania na podstawie pewnych warunków." _ Https://msdn.microsoft.com/en-us/library/dd321457%28v = vs.110% 29.aspx –