2009-12-22 5 views
1

J'ai une application C# qui a une interface utilisateur et des threads d'arrière-plan. Basé sur l'entrée de l'utilisateur, j'aime arrêter et démarrer le fil d'arrière-plan. J'ai deux options que je vois.Comment démarrer et arrêter le thread d'arrière-plan encore et encore?

1) arrêter totalement et puis commencer fil d'arrière-plan en tant que nouveau fil (je ne l'ai pas été en mesure à ce que je continue à recevoir mon processus de message terminé)

2) mettre en pause le le fil d'arrière-plan jusqu'à ce que l'utilisateur clique à nouveau sur

Voici le code que j'appelle à nouveau après bw.CancelAsync();

private void StartBackgroundWorker() 
    { 
     bw = new BackgroundWorker(); 
     bw.WorkerReportsProgress = true; 
     bw.WorkerSupportsCancellation = true; 
     bw.DoWork += bw_DoWork; 
     bw.RunWorkerCompleted += bw_RunWorkerCompleted; 
     bw.RunWorkerAsync("Background Worker"); 
    } 

Merci d'avance pour votre aide.

+0

Vous ne savez pas exactement ce que vous demandez ici - voyez-vous une erreur? – itowlson

+0

Dans quel but faites-vous cela? –

+0

pourquoi ne pas utiliser ThreadPool? – lsalamon

Répondre

1

Vous ne pouvez pas démarrer et arrêter un travail d'arrière-plan de cette manière, mais dans votre événement DoWork, vous pouvez lui demander s'il doit s'exécuter ou attendre. Vous pouvez également sous-classer BackgroundWorker (remplacer la méthode OnDoWork()), et y ajouter des méthodes start/pause qui basculent un handle d'attente privé, ce qui est beaucoup plus agréable que d'avoir votre interface utilisateur à propos de ManualResetEvent.

//using System.Threading; 

//the worker will ask this if it can run 
ManualResetEvent wh = new ManualResetEvent(false); 

//this holds UI state for the start/stop button 
bool canRun = false; 

private void StartBackgroundWorker() 
{ 
    bw = new BackgroundWorker(); 
    bw.WorkerReportsProgress = true; 
    bw.WorkerSupportsCancellation = true; 
    bw.DoWork += bw_DoWork; 
    bw.RunWorkerCompleted += bw_RunWorkerCompleted; 
    bw.RunWorkerAsync("Background Worker"); 
} 


void bw_DoWork(object sender, DoWorkEventArgs e) 
{ 
    while(true) 
    { 
      //it waits here until someone calls Set() on wh (via user input) 
      // it will pass every time after that after Set is called until Reset() is called 
      wh.WaitOne() 

     //do your work 

    } 
} 


//background worker can't start until Set() is called on wh 
void btnStartStop_Clicked(object sender, EventArgs e) 
{ 
    //toggle the wait handle based on state 
    if(canRun) 
    { 
     wh.Reset(); 
    } 
    else {wh.Set();} 

    canRun= !canRun; 
    //btnStartStop.Text = canRun ? "Stop" : "Start"; 
} 
0

Vous pouvez toujours abandonner un thread et intercepter l'exception ThreadAbortedException. Je ne suis pas sûr si c'est la solution la plus soignée puisqu'une exception cause beaucoup de surcharge mais je pense que c'est mieux que de répandre WaitOne dans le code comme Dan l'a suggéré.

Une autre solution consiste à hériter de la classe de threads et à ajouter une fonction à cette classe qui arrête ou suspend le thread. De cette façon, vous pouvez masquer les détails de l'implémentation.

Questions connexes