2012-07-03 20 views
5

Ich verwende System.ComponentModel.BackgroundWorker in meiner WPF Anwendung. Wie kann ich für BackgroundWorker setzen?Timeout für BackgroundWorker

+1

Timeout, was zu tun? – Dimitri

+1

etwas, es tut etwas, und ich möchte aufhören nach der Zeitüberschreitung. –

+0

Ja, wie BugFinder sagte, verwenden Sie Abbruch-Token, um aus der Ausführung abzubrechen – Dimitri

Antwort

4

Mein Vorschlag folgt

backgroundworker1 macht die Arbeit - es Stornierung akzeptiert, so dass Sie können aufhören zu machen.

backgroundworker2 macht eine Schleife, während die Zeitüberschreitung aussteht und die Zeitüberschreitung abgeschlossen ist.

Wenn backgroundworker1 noch läuft, die RunWorkerComplete dieser BackgroundWorker, tötet backgroundworker1 ..

Dies sollte auch Stornierung akzeptieren so, dass, wenn backgroundworker1 abgeschlossen ist und diese noch läuft , Sie können es abbrechen.

+0

ein anderer Thread de facto, ist nicht einfach, ein anderer Weg? –

+0

Wahrscheinlich, aber um eine ziemlich genaue Auszeit zu bekommen, sowie die Funktionalität gibt es nicht viele Optionen. Sie könnten irgendeine Form von Nachkommen machen und ständig nach der Zeit suchen, die in Ihrem ursprünglichen Arbeiter vergangen ist, aber wenn Sie irgendeine Form von blockierendem Anruf hatten, könnte es das Zeitlimit überschreiten. – BugFinder

4

BackgroundWorker unterstützt ein Timeout nicht direkt, aber es unterstützt die Löschung. Dies funktioniert gut, wenn die Arbeit eine Schleife oder eine andere Struktur ist, in der Sie regelmäßig überprüfen können, dass das CancellationPending-Mitglied dann abbricht. Sie benötigen etwas anderes, um dem Hintergrundarbeiter zu sagen, dass er nach dem Timeout abbrechen soll. Hier habe ich einen asynchronen Aufruf einer Aktion verwendet.

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 
      } 
     } 
    } 

Ist dies nicht wirklich passt, was Ihr wollen Sie erreichen können bei Implementing a timeout on a function returning a value oder Implement C# Generic Timeout gefunden in den allgemeinen Timeout Lösungen interessiert. Sie können diese im BackgroundWorker verwenden.

+0

Vielen Dank aber es funktioniert nicht, EventArgs.Cancel wird nie wahr. –

+0

@ArmenKhachatryan Oh, natürlich ist es nicht, ich habe das falsche Objekt für Abbrechen Informationen überprüft (^ _ ^;). Ich habe es mit einem Fix bearbeitet. – vossad01

+0

Funktioniert wie ein Charme. Vielen Dank .... Wenn Sie OO-Modus gehen ;-), können Sie Global var bg = new BackgroundWorker und verwenden Sie CancelAsync(); überall in deinem Code. –