Come faccio a iniziare e smettere di thread in background più e più volte?
-
21-09-2019 - |
Domanda
Ho c # app che ha interfaccia utente e thread in background. In base all'input dell'utente che mi piace per arrestare e avviare il thread in background. Ho due opzioni qui come la vedo io:
1) completamente fermo e poi comincio thread in background come nuovo thread (io non sono stato capace di questo. Continuo a ricevere il mio processo messaggio terminato)
2) Mettere in pausa il thread in background fino a quando l'utente clicca di nuovo run.
Ecco il codice che io chiamo di nuovo dopo 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");
}
Grazie in anticipo per il vostro aiuto.
Soluzione
Non è possibile avviare e arrestare un operaio di fondo del genere, ma nel tuo caso DoWork, si può avere chiesto se deve eseguire o aspettare.
è anche possibile creare una sottoclasse BackgroundWorker (l'override del metodo OnDoWork ()), e aggiungere metodi di avvio / pausa ad esso che passare l'impugnatura di attesa privata, che è molto più bello di avere l'interfaccia utente a conoscenza del 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";
}
Altri suggerimenti
Si può sempre interrompere un filo e prendere il ThreadAbortedException. Non sono sicuro se questa è la soluzione più pulita dal un'eccezione provoca un sacco di spese generali, ma penso che sia meglio che la diffusione WaitOne nel codice come Dan ha suggerito.
Un'altra soluzione è quella di ereditare dalla classe filo, e aggiungere una funzione di questa classe che arresta o sospende il filo. In questo modo è possibile nascondere i dettagli di attuazione.