2012-07-03 24 views
5

Sto usando System.ComponentModel.BackgroundWorker nella mia applicazione WPF.Timeout per BackgroundWorker

Come impostare timeout per BackgroundWorker?

+1

timeout per fare cosa? – Dimitri

+1

qualcosa, fa qualcosa, e voglio smettere di farlo dopo un timeout. –

+0

Sì, come ha detto BugFinder usa il token di cancellazione per annullare l'esecuzione – Dimitri

risposta

4

Il mio suggerimento è seguendo

backgroundworker1 fa il lavoro - accetta la cancellazione in modo da poter farlo smettere.

backgroundworker2 esegue un ciclo mentre il timeout è in sospeso e il timeout viene completato.

Se backgroundworker1 è ancora in esecuzione, il RunWorkerComplete di questo BackgroundWorker, uccide backgroundworker1 ..

Questo dovrebbe anche accettare cancellazione in modo che se backgroundworker1 Completa e questo è ancora in esecuzione , puoi cancellarlo.

+0

un altro thread di fatto, non è affatto facile, un altro modo? –

+0

Probabilmente ma, per ottenere un timeout abbastanza preciso, oltre alla funzionalità, non ci sono molte opzioni. Potresti fare una qualche forma di discendente e controllare costantemente il tempo trascorso nel tuo lavoratore originale, ma, se hai qualche forma di chiamata di blocco, potrebbe superare il timeout. – BugFinder

4

BackgroundWorker non supporta direttamente un timeout, ma supporta la cancellazione. Ciò funzionerà bene se il lavoro in corso è un ciclo o un'altra struttura in cui è possibile controllare periodicamente il membro CancellationPending per poi interromperlo. Avrai bisogno di qualcos'altro per dire al lavoratore in background di annullare dopo il timeout. Qui ho usato una chiamata asincrona di un'azione.

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

Se questo in realtà non si adatta ciò che stai cercando di realizzare che si può essere interessati a soluzioni di timeout generiche trovate a Implementing a timeout on a function returning a value o Implement C# Generic Timeout. Potresti usare quelli all'interno di BackgroundWorker.

+0

Grazie ma non funziona, eventArgs.Cancel non si avvererà mai. –

+0

@ArmenKhachatryan Oh, certo che no, stavo controllando l'oggetto sbagliato per cancellare le informazioni (^ _ ^;). Ho modificato con una correzione. – vossad01

+0

Funziona come un fascino. Molte grazie .... Se stai andando in modalità OO ;-), puoi Global var bg = new BackgroundWorker e usare CancelAsync(); ovunque nel tuo codice. –