2012-07-03 24 views
5

Używam aplikacji System.ComponentModel.BackgroundWorker w mojej aplikacji WPF.Limit czasu dla BackgroundWorker

Jak ustawić timeout dla BackgroundWorker?

+1

limit czasu, aby zrobić co? – Dimitri

+1

coś, to coś robi i chcę przestać robić to po timeout. –

+0

Tak, jak BugFinder powiedział, że używa tokena anulowania, aby anulować wykonanie – Dimitri

Odpowiedz

4

Moja propozycja jest następująca

backgroundworker1 działa - akceptuje anulowanie więc można je zatrzymać.

backgroundworker2 wykonuje pętlę w oczekiwaniu na przekroczenie limitu czasu i kończy czas oczekiwania.

Jeśli backgroundworker1 jest jeszcze uruchomiony, RunWorkerComplete tego BackgroundWorker, zabija backgroundworker1 ..

ten powinien również przyjąć anulowanie tak, że jeśli backgroundworker1 finalizuje a ten nadal działa , możesz to anulować.

+0

inny wątek de facto, nie jest łatwy, inny sposób? –

+0

Prawdopodobnie, aby uzyskać dość dokładny czas, a także funkcjonalność, nie ma wielu opcji. Możesz zrobić jakąś formę potomka i stale sprawdzać, czy upłynął czas w oryginalnym pracowniku, ale gdybyś miał jakąś formę blokowania, to może to znacznie przekroczyć limit czasu. – BugFinder

4

BackgroundWorker nie obsługuje bezpośrednio limitu czasu, ale obsługuje anulowanie. To zadziała dobrze, jeśli wykonywana praca jest pętlą lub inną strukturą, w której można okresowo sprawdzać członka anulowania, aby przerwać. Będziesz potrzebował czegoś innego, aby powiedzieć pracownikowi tła, aby anulował po upływie limitu czasu. Tutaj użyłem asynchronicznego wywołania akcji.

static void Main(string[] args) 
    { 
     var bg = new BackgroundWorker { WorkerSupportsCancellation = true }; 
     bg.DoWork += LongRunningTask; 

     const int Timeout = 500; 
     Action a =() => 
      { 
       Thread.Sleep(Timeout); 
       bg.CancelAsync(); 
      }; 
     a.BeginInvoke(delegate { }, null); 

     bg.RunWorkerAsync(); 

     Console.ReadKey(); 
    } 

    private static void LongRunningTask(object sender, DoWorkEventArgs eventArgs) 
    { 
     var worker = (BackgroundWorker)sender; 
     foreach (var i in Enumerable.Range(0, 5000)) 
     { 
      if (worker.CancellationPending) 
      { 
       return; 
      } 
      else 
      { 
       //Keep working 
      } 
     } 
    } 

Jeśli to nie bardzo pasuje co się chce osiągnąć może być zainteresowany w ogólnych rozwiązań limitu czasu znaleźć na Implementing a timeout on a function returning a value lub Implement C# Generic Timeout. Możesz użyć tych wewnątrz BackgroundWorker.

+0

Dziękujemy, ale to nie działa, eventArgs.Cancel nigdy się nie spełni. –

+0

@ArmenKhachatryan Och, oczywiście, że nie, sprawdzałem zły obiekt dla anulowania informacji (^ _ ^;). Edytowałem z poprawką. – vossad01

+0

Działa jak urok. Wielkie dzięki .... Jeśli wybierasz tryb OO ;-), Twój może Global var bg = nowy BackgroundWorker i użyj CancelAsync(); w dowolnym miejscu w kodzie. –