2009-06-28 16 views
10

Sto cercando un modo per riavviare un filo che è stato fermato da Abort() ..Riavvio di un filo a .NET (con C#)

public partial class MyProgram : Form 
{ 
    private Thread MyThread = new Thread(MyFunction); 
    private System.Windows.Forms.Button startStopBtn = new System.Windows.Forms.Button(); 
    public MyProgram() 
    { 
    MyThread.Start(); 
    startStopBtn += new EventHandler(doStop); 
    startStopBtn.Text = "Stop"; 
    } 
    private static void MyFunction() 
    { 
    // do something 
    } 
    private void doStop(object sender, EventArgs e) 
    { 
    MyThread.Abort(); 
    startStopBtn -= new EventHandler(doStop); 
    startStopBtn += new EventHandler(doStart); 
    startStopBtn.Text = "Start"; 
    } 
    private void doStart(object sender, EventArgs e) 
    { 
    MyThread.Start(); // << Error returned when clicking the button for 2nd time 
    startStopBtn -= new EventHandler(doStart); 
    startStopBtn += new EventHandler(doStop); 
    startStopBtn.Text = "Stop"; 
    } 
} 

Qualche idea?

risposta

12

Basta aggiungere MyThread = new Thread (MyFunction) prima di chiamare MyThread.Start() in doStart(). Non creare il thread al di fuori dei tuoi metodi, lo spazio lì è pensato per le dichiarazioni.

MODIFICA: Si noti che uccidere un thread con thread.Abort() può essere molto pericoloso. Dovresti cercare di ottenere un multithreading pulito, come Groo descritto nel suo post.

+0

Questa risposta è più una soluzione alternativa che una risposta reale. Non ho nemmeno spiegato il motivo per cui ha un errore Groo ha ragione, – Trap

+3

Hai ragione, ma quando ero un principiante di programmazione, avevo molti problemi simili: stavo leggendo molte soluzioni come quella di Groo, e sì, hai perfettamente ragione, la mia soluzione è solo una soluzione. Ma i meccanismi che Groo descrive erano troppo complessi per me da comprendere nella mia programmazione, nuovi tempi. Quindi, forse, sarebbe meglio fornire una semplice "risposta" (o soluzione alternativa) per un programmatore non così esperto – Emiswelt

+0

Questa è la roba che rende i programmatori cattivi, non investono abbastanza tempo per capire cosa stanno facendo. o sta per ripulire il tuo thread.Abort casino quando te ne sei andato? –

2

No, non c'è, ma perché vorresti? Basta avviare un nuovo thread, con lo stesso ThreadStart e lo stesso parametro (se presente).

6

La semplice risposta è, non è possibile. Una volta che un thread è stato interrotto, non è possibile riavviarlo. Basta creare un metodo o qualcosa, che restituisca un oggetto Thread esattamente come ne hai bisogno. Quando hai bisogno di una nuova discussione, prendila da quel metodo.

29

Una volta interrotta la discussione, non è possibile riavviarla.

Ma il tuo problema attuale è che tu sei abortire il tuo thread. Devi never use Thread.Abort().

Se il thread deve essere messo in pausa e continuato più volte, è consigliabile prendere in considerazione l'utilizzo di altri meccanismi (ad esempio AutoResetEvent, ad esempio).

[EDIT]

La soluzione più semplice per interrompere un filo, come menzionato da Ian Griffiths nel link qui sopra, è:

L'approccio che ho sempre consiglio è morto semplice. Avere un campo volatile bool visibile sia per il thread di lavoro che per il thread dell'interfaccia utente. Se l'utente fa clic su Annulla, imposta questo flag. Nel frattempo, sul tuo thread di lavoro, prova di volta in volta. Se vedi che viene impostato, interrompi ciò che stai facendo.

L'unica cosa che dovete fare per farlo funzionare correttamente, è quello di riorganizzare il metodo di sfondo in modo che venga eseguito in un ciclo - in modo da poter controllare periodicamente se il flag è stato impostato da un filo diverso

Se è necessario mettere in pausa e riprendere le funzionalità per lo stesso thread di lavoro, anziché il semplice approccio flag volatile bool, è possibile optare per un approccio leggermente più complesso, un costrutto di sincronizzazione come AutoResetEvent. Queste classi forniscono anche un modo per sospendere il thread worker per un intervallo di tempo specificato (o indefinito) tra i segnali dal thread non worker.

This thread contiene un esempio concreto con i metodi Start, Pause, Resume e Stop. Si noti come l'esempio di Brannon non interrompe mai il thread.. Spara solo un evento, quindi attende che il thread termini con grazia.

0

Se è davvero necessario interrompere la funzione thread e riprendere, è necessario impostare una condizione e controllarla periodicamente durante l'elaborazione.

Ciò consentirebbe di interrompere l'elaborazione per un certo periodo di tempo e quindi riprendere.

Ho usato eventi e chiamate di attesa per svolgere un compito simile.

0

Il modo più semplice è non interrompere la discussione.

-3

Davvero non capisco perché le persone forniscano informazioni se non sanno che è corretto. Come può un programmatore reale sospendere o interrompere l'elaborazione di un thread per qualche tempo e quindi rilasciarlo rendendo il codice vulnerabile. . @ Brad-- m dispiace .. ma la tua idea non era buono .. @Rhythmic - Hai bisogno di lavorare sul vostro modo di affrontare le cose ..

BFree era un po 'destra se la gente lo ha ottenuto nello stesso modo Voleva dire .. Hai solo bisogno di ri-dichiarare che ..

qui sotto è l'esempio:

Public Shared Sub ResetAbort() 

    Dim ThreadPleaseWait As New Thread(New ThreadStart(AddressOf YourSubName)) 

    YourThreadName.Start() 

    Thread.Sleep(2000) 

    YourThreadName.Abort() 

End Sub 

Ora è possibile utilizzare questo Sub ovunque si desideri avviare il thread. Interromperà automaticamente il thread.

Se si desidera avviare la discussione sulla Button1_Click() evento e fermarlo sul Button2_Click() evento Usa questo:

in Button1_Click() evento

Dim ThreadPleaseWait As New Thread(New ThreadStart(AddressOf YourSubName)) 

    YourThreadName.Start() 

in button2_Click() evento

YourThreadName.Start() 

in questo modo si interromperà il thread dove si desidera e verrà inizializzato di nuovo. Puoi anche usare la proprietà YourThreadName.ThreadState.Running per verificare se il thread è in esecuzione o meno (Giusto per evitare più istanze dello stesso thread .....

+5

Correggi la tua formattazione. Inoltre, mentre lo stai modificando, potresti voler renderlo un po 'meno belligerante. Mentre non ti piace la parola "no", non è possibile riavviare * un thread interrotto *. Cosa OP richiesto non è possibile. Inoltre, Thread.Abort() è considerato dannoso. Esistono modi molto migliori per controllare l'esecuzione del thread. Non servi il richiedente lasciandolo continuare a fare cose cattive. Meglio dare alternative che soddisfino le sue esigenze senza incorrere nello stesso rischio. – Will