Каковы альтернативные способы приостановить и возобновить поток?

Два методаThread.Suspend() а такжеThread.Resume() устарели начиная с .NET 2.0. Зачем? Какие есть другие альтернативы и примеры?

Ответы на вопрос(7)

Это слишком долго. Что мне нужно, это быстрый пример кода для использования. Я нашел один из обсуждения и ответил Марк Р. Доусон вhttp://bytes.com/groups/net-c/458947-thread-suspend, Это объясняет опасность устаревших методов и как использовать AutoResetEvent, чтобы уведомить второй поток о продолжении обработки.

Причины почемуThread.Suspend() а такжеThread.Resume() устарели или удалены в .NET по большей части те же причины, по которымThread.suspend() а такжеThread.resume() устарели в Java. Compare-

в JavaЧасто задаваемые вопросы об устаревшем потоке (suspend "по своей сути тупиковый"), сМарк Р. Доусонответ на .NET Thread.Suspend () ` («Если вы остановите поток в середине исполнения, вы можете столкнуться с тупиком и условиями гонки»).

Вы можете использовать ManualReset вместо AutoReset:

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

 }
 }
}

Я согласен, что это отличный учебник. Основная причина, по которой Suspend () и Resume () устарели, заключается в том, что они являются довольно опасными методами. В любой момент Thread t мог делать что угодно. Что-нибудь. Представьте, что ваш поток читает файл и заблокирован. Вы приостановили свою тему. Файл остается заблокированным. То же самое касается любых других ресурсов. То же самое касается блокировки мьютекса.

Это лучшее учебное пособие для Thread (для C #):http://www.albahari.com/threading/

Для ожидания вам нужно использовать .Join () в потоке. Это будет ждать, пока финишная обработка не станет работой. В противном случае вам нужно будет использоватьПодождите / Pulse.

 Elisabeth09 мая 2019 г., 18:32
.Join () завершает поток

Все хорошие альтернативы работают в потоке, достигая точки, в которой он с радостью ждет. Приостановка была опасной, потому что она могла приостановить поток, пока он удерживал блокировку на мьютексе - рецепт для взаимоблокировок.

Так что вашему потоку нужен объект ManualResetEvent, который он может ожидать - в то время, когда это безопасно для него, когда он не удерживает никаких блокировок.

 Szymon Rozga19 дек. 2008 г., 22:04
Хороший вопрос с ManualResetEvent. Вы также можете использовать AutoResetEvent.

Вы хотите использовать AutoResetEvent EventWaitHandle.

Скажи, что хочешь сделать что-то подобное (НОТАне делай этого!

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. Он работает так же, как и Suspend / Resume, так как AutoResetEvent позволяет «возобновить» только один поток.

 Marc Climent26 окт. 2010 г., 17:33
Это решает типичные ситуации приостановки / возобновления и позволяет избежать устаревших предупреждений.
 siride25 нояб. 2014 г., 22:32
@zespri: эээ, как?Suspend() а такжеResume() методы наThread класс, который связан с многопоточностью. Это плохие методы по той же причине, по которой завершение процесса хуже, чем его завершение.
 Andrew Savinykh25 нояб. 2014 г., 22:45
@ Sirid, вы всегда должны стремиться к модульности. Если вы можете написать свой код так, чтобы вашему рабочему потоку не приходилось выполнять управление потоками и вызывать какие-либо методы вThread класс вообще - ты молодец Изоляция всего кода управления потоками вне рабочих потоков идеальна - к сожалению, это не часто достигается.Suspend / Resume в частности, был (был) один сценарий, когда это возможно.
 srcspider17 сент. 2015 г., 14:40
Этот метод будет работать только для ОДНОЙ НИТИ, в общем, при использовании многопоточности у вас будет НЕСКОЛЬКО рабочих потоков. Кстати, метод Suspend / Resume отлично подойдет для нескольких потоков. Честно говоря, учитывая, что независимо от того, как вы приостанавливаете поток, вы все равно приостанавливаете какие-либо обработчики, логика, почему Suspend / Resume считается устаревшей или плохой практикой, хотя даже в приведенном выше примере это будет работать просто отлично, - это полная чушь для MS ,
 siride26 нояб. 2014 г., 01:54
@zespri: на самом деле, события более абстрактны. (1) Они вообще не должны использоваться с потоками. (2) Они отвечают на вопрос "верно ли какое-то условие, чтобы я мог продолжить?" без ссылки на то, где это условие установлено. (3) Приостановить / возобновить банкутолько использоваться с потоками, поэтому они вообще не предлагают абстрагирование от потоков.
 Andrew Savinykh09 дек. 2013 г., 08:05
Это означает, что вы должны поставить логику потоковвнутри ваша нить. Приостановить возобновление позволяет вам писать код, который, к счастью, не знает ни о каком потоке.

Ваш ответ на вопрос