2011-01-31 8 views
13

Come mettere in pausa il thread e continuare quando si verificano alcuni eventi?C#: come mettere in pausa il thread e continuare quando si verificano alcuni eventi?

Desidero che il thread continui quando si fa clic sul pulsante. Qualcuno dice che thread.suspend non è il modo corretto di mettere in pausa il thread. Poi un'altra soluzione?

+0

si potrebbe usare un [System.Threading.EventWaitHandle] (http: // msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.aspx) – Marlon

+0

@Marlon avresti potuto dirlo in risposta ... –

risposta

12

È possibile utilizzare uno System.Threading.EventWaitHandle.

Un EventWaitHandle blocca fino a quando non viene segnalato. Nel tuo caso verrà segnalato dall'evento click del pulsante.

private void MyThread() 
{ 
    // do some stuff 

    myWaitHandle.WaitOne(); // this will block until your button is clicked 

    // continue thread 
} 

È possibile segnalare la vostra maniglia di attesa in questo modo:

private void Button_Click(object sender, EventArgs e) 
{ 
    myWaitHandle.Set(); // this signals the wait handle and your other thread will continue 
} 
+1

Come inizializzare EventWaitHandler correttamente? È new EventWaitHandler (false, EventResetMode.AutoReset) –

+0

Faccio 'new EventWaitHandle (false, EventResetMode.ManualReset)'. 'false' inizializza EventWaitHandle con unsignaled, quindi bloccherà. – Marlon

+0

Questo video mi ha aiutato a capire https://www.youtube.com/watch?v=xaaRBh07N34 – reggaeguitar

6

In effetti, sospendere un thread è una cattiva pratica poiché raramente si conosce esattamente cosa sta facendo un thread in quel momento. È più prevedibile che il thread passi oltre un ManualResetEvent, chiamando ogni volta WaitOne(). Questo fungerà da gate: il thread di controllo può chiamare Reset() per chiudere il gate (mettendo in pausa il thread, ma in modo sicuro) e Set() per aprire il gate (riprendendo il thread).

Ad esempio, è possibile chiamare WaitOne all'inizio di ogni iterazione del ciclo (o una volta ogni n iterazioni se il ciclo è troppo stretto).

2

si può provare questo anche

private static AutoResetEvent _wait = new AutoResetEvent(false); 

public Form1() 
    { 
     InitializeComponent(); 
    } 

private void Form1_Load(object sender, EventArgs e) 
    { 
     Control.CheckForIllegalCrossThreadCalls = false; 
     backgroundWorker1.RunWorkerAsync(); 
    } 
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     Dosomething(); 
    } 

private void Dosomething() 
{ 
//Your Loop 
for(int i =0;i<10;i++) 
    { 
    //Dosomething 
    _wait._wait.WaitOne();//Pause the loop until the button was clicked. 

    } 
} 

private void btn1_Click(object sender, EventArgs e) 
    { 
     _wait.Set(); 
    }