it-swarm.com.de

Was sind alternative Möglichkeiten, um einen Thread anzuhalten und fortzusetzen?

Die beiden Methoden Thread.Suspend() und Thread.Resume() sind seit .NET 2.0 veraltet. Warum? Was sind andere Alternativen und Beispiele?

23
David.Chu.ca

Sie sollten ein AutoResetEvent EventWaitHandle verwenden.

Angenommen, Sie möchten so etwas tun (NOTE: mach das nicht!): 

private Thread myThread;

private void WorkerThread() 
{
    myThread = Thread.CurrentThread;
    while (true)
    {
        myThread.Suspend();
        //Do work.
    }
}

public void StartWorking() 
{
    myThread.Resume();
}

Wie andere schon gesagt haben, ist dies eine schlechte Idee. Obwohl die Verwendung von Suspend für einen eigenen Thread relativ sicher ist, können Sie nie herausfinden, ob Sie Resume aufrufen, wenn der Thread tatsächlich angehalten ist. Suspend und Resume sind also veraltet. 

Stattdessen möchten Sie ein AutoResetEvent verwenden:

private EventWaitHandle wh = new AutoResetEvent();

private void WorkerThread() 
{
    while(true) 
    {
        wh.WaitOne();
        //Do work.
    }
}

public void StartWorking()
{
    wh.Set();
}

Der Worker-Thread wartet auf den Wait-Handle, bis ein anderer Thread StartWorking aufruft. Es funktioniert im Wesentlichen wie Suspend/Resume, da mit AutoResetEvent nur ein Thread "fortgesetzt" werden kann. 

20
Darcy Casselman

Die guten Alternativen funktionieren alle, indem der Thread einen Punkt erreicht, an dem er gerne wartet. Das Suspendieren war gefährlich, da der Thread dadurch angehalten werden konnte, während er auf einem Mutex eine Sperre hielt - ein Rezept für Deadlocks.

Ihr Thread benötigt also ein ManualResetEvent, auf das er warten kann - zu einem Zeitpunkt, zu dem es sicher ist, dass er es tut, wenn er keine Sperren hält.

11

Dies ist das beste Tutorial für Thread (für C #): http://www.albahari.com/threading/

Zum Warten müssen Sie .Join () für den Thread verwenden. Dies wird warten, bis das Profil fertig ist. Andernfalls müssen Sie Wait/Pulse verwenden.

4

sie können ManualReset anstelle von AutoReset verwenden:

public class Worker
{
 ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
 ManualResetEvent _pauseEvent = new ManualResetEvent(true);
 Thread _thread;

public Worker() { }

public void Start()
 {
 _thread = new Thread(DoWork);
 _thread.Start();
 Console.WriteLine("Thread started running");
 }

public void Pause()
 {
 _pauseEvent.Reset();
 Console.WriteLine("Thread paused");
 }

public void Resume()
 {
 _pauseEvent.Set();
 Console.WriteLine("Thread resuming ");
 }

public void Stop()
 {
 // Signal the shutdown event
 _shutdownEvent.Set();
 Console.WriteLine("Thread Stopped ");

// Make sure to resume any paused threads
 _pauseEvent.Set();

// Wait for the thread to exit
 _thread.Join();
 }

public void DoWork()
 {
 while (true)
 {
 _pauseEvent.WaitOne(Timeout.Infinite);

if (_shutdownEvent.WaitOne(0))
 break;

// Do the work..
 Console.WriteLine("Thread is running");

 }
 }
}
1
Luke

Das ist zu lang. Was ich brauche, ist ein schneller Beispielcode. Ich fand eine aus der Diskussion und antwortete von Mark R. Dawson unter http://bytes.com/groups/net-c/458947-thread-suspend . Es erklärt die Gefahr der veralteten Methoden und wie AutoResetEvent verwendet wird, um den zweiten Thread zu benachrichtigen, um die Verarbeitung fortzusetzen.

1
David.Chu.ca

Die Gründe, warum Thread.Suspend() und Thread.Resume() in .NET obsolet sind oder aus dem Netzwerk entfernt werden, sind im Wesentlichen die gleichen Gründe, warum Thread.suspend() und Thread.resume() in Java veraltet sind. Vergleichen Sie-

0
Peter O.

Ich stimme zu, dass dies ein großartiges Tutorial ist. Der Hauptgrund, warum Suspend () und Resume () obsolet sind, liegt darin, dass sie ziemlich gefährliche Methoden sind. An jedem Punkt könnte Thread t irgendetwas tun. Etwas. Stellen Sie sich vor, Ihr Thread liest eine Datei und hat eine Sperre. Sie setzen Ihren Thread aus. Datei bleibt gesperrt Gleiches gilt für alle anderen Ressourcen. Dasselbe gilt für eine Sperre für einen Mutex.

0
Szymon Rozga