Перезапуск потока в .NET(с использованием С#)

Я ищу способ перезапуска потока, который был остановлен Abort()..

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

Любая идея?

Ответ 1

Просто добавьте MyThread = новую тему (MyFunction) перед вызовом MyThread.Start() в doStart(). Не создавайте поток за пределами ваших методов, пространство для деклараций.

РЕДАКТИРОВАТЬ: Обратите внимание, что уничтожение потока с помощью thread.Abort() может быть очень опасным. Вы должны попытаться выполнить чистую многопоточность, как описано в его статье.

Ответ 2

Как только вы прервали свою нить, вы не сможете запустить ее снова.

Но ваша фактическая проблема заключается в том, что вы прервите свою нить. Вы должны никогда не использовать Thread.Abort().

Если ваш поток должен быть приостановлен и продолжен несколько раз, вам следует рассмотреть возможность использования других механизмов (например, AutoResetEvent).

[EDIT]

Самое простое решение прервать поток, как указано в Ian Griffiths в приведенной выше ссылке:

Подход, который я всегда рекомендую, прост. Имейте поле volatile bool, которое отображается как для рабочего потока, так и для вашего потока пользовательского интерфейса. Если пользователь нажимает кнопку "Отменить", установить этот флаг. Между тем, на ваш рабочий поток, проверить флаг время от времени. Если вы видите, что он установлен, прекратите то, что вы делаете.

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

Если вам нужен режим паузы и возобновления для одного и того же рабочего потока, вместо простого подхода флага volatile bool, вы можете пойти на несколько более сложный подход - такую ​​конструкцию синхронизации, как AutoResetEvent. Эти классы также предоставляют возможность помещать рабочий поток в заданный (или неопределенный) промежуток времени между сигналами от нерабочего потока.

Этот поток содержит конкретный пример с методами "Пуск", "Пауза", "Возобновить" и "Остановить". Обратите внимание, что пример Браннона никогда прерывает поток. Он только запускает событие, а затем ждет, пока поток закончится изящно.

Ответ 3

Простой ответ: вы не можете. Как только поток был прерван, его нельзя перезапустить. Просто создайте метод или что-то еще, что возвращает объект Thread именно так, как вам это нужно. Когда вам нужен новый Thread, просто получите его от этого метода.

Ответ 4

Нет, нет, но зачем вам это нужно? Просто запустите новый поток с тем же ThreadStart и тем же параметром (если есть).

Ответ 5

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

Это позволит вам прекратить обработку в течение некоторого времени и затем возобновить.

Я использовал события и Подождите, чтобы выполнить аналогичную задачу.

Ответ 6

Самый простой способ - не прервать поток.

Ответ 7

Я действительно не понимаю, почему люди предоставляют информацию, если они не знают, что это правильно. Как может настоящий программист приостановить или прекратить обработку потока на некоторое время, а затем освободить его и тем самым сделать код уязвимым... @Брэд - извините.. но ваша идея не была хороша.. @Rhythmic - вам нужно работать на вашем пути, чтобы приблизиться к вещам.

BFree был несколько прав, если вы получили его так же, как он хотел сказать. Вам просто нужно повторно объявить, что..

Ниже приведен пример

:

Public Shared Sub ResetAbort()

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

    YourThreadName.Start()

    Thread.Sleep(2000)

    YourThreadName.Abort()

End Sub

Теперь вы можете использовать этот Sub везде, где хотите начать поток. Он автоматически прервет поток.

Если вы хотите запустить поток в событии Button1_click() и остановить его на событии Button2_Click(), используйте это:

в событии Button1_click()

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

    YourThreadName.Start()

в событии Button2_click()

    YourThreadName.Start()

таким образом вы прервите поток, где захотите, и снова его инициализируете. Вы также можете использовать свойство YourThreadName.ThreadState.Running, чтобы проверить, работает ли поток или нет (просто чтобы избежать нескольких экземпляров одного и того же потока.....