web-dev-qa-db-ja.com

スレッドを一時停止および再開する別の方法は何ですか?

2つのメソッドThread.Suspend()およびThread.Resume()は、.NET 2.0から廃止されました。どうして?他の選択肢と例は何ですか?

25
David.Chu.ca

AutoResetEvent EventWaitHandleを使用する必要があります。

このようなことをしたいとしましょう([〜#〜] note [〜#〜]:これを行わないでください!):

private Thread myThread;

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

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

他の人が言ったように、これは悪い考えです。独自のスレッドでSuspendのみを使用することは比較的安全ですが、スレッドが実際に中断されているときにResumeを呼び出しているかどうかはわかりません。そのため、SuspendとResumeは廃止されました。

代わりに、AutoResetEventを使用します。

private EventWaitHandle wh = new AutoResetEvent();

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

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

ワーカースレッドは、別のスレッドがStartWorkingを呼び出すまで待機ハンドルで待機します。 AutoResetEventでは1つのスレッドのみを「再開」できるため、Suspend/Resumeとほぼ同じように機能します。

20
Darcy Casselman

良い代替手段はすべて、スレッドが待機して喜んでいるポイントに到達することで機能します。スレッドがmutexにロックを保持しているときにスレッドを一時停止する可能性があるため、一時停止は危険でした-デッドロックのレシピ。

したがって、スレッドに必要なのは、ロックを保持していない安全なときに、待機できるManualResetEventです。

11

これは、スレッド(C#の場合)の史上最高のチュートリアルです。 http://www.albahari.com/threading/

待機するには、スレッドで.Join()を使用する必要があります。これは、トレッドの仕上げが仕事になるまで待機します。それ以外の場合は、 Wait/Pulse を使用する必要があります。

4

autoResetの代わりにManualResetを使用できます。

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");

 }
 }
}
3
Luke

あれは長すぎる。必要なのは、使用する簡単なサンプルコードです。私はディスカッションから1つ見つけ、Mark R. Dawsonが http://bytes.com/groups/net-c/458947-thread-suspend で回答しました。廃止されたメソッドの危険性と、AutoResetEventを使用して2番目のスレッドに処理を続行するよう通知する方法について説明します。

1
David.Chu.ca

Thread.Suspend()およびThread.Resume()が.NETで廃止または削除された理由は、JavaでThread.suspend()およびThread.resume()が廃止された理由とほぼ同じです。 。比較—

0
Peter O.

すばらしいチュートリアルだと思います。 Suspend()とResume()が廃止された主な理由は、かなり危険なメソッドだからです。どの時点でも、スレッドtは何でも実行できます。なんでも。スレッドがファイルを読み取り、ロックしているとします。スレッドを一時停止します。ファイルはロックされたままです。他のリソースについても同様です。ミューテックスのロックについても同様です。

0
Szymon Rozga