Перезапуск потока в .NET (с использованием C #) - PullRequest
13 голосов
/ 28 июня 2009

Я ищу способ перезапустить поток, который был остановлен 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";
  }
}

Есть идеи?

Ответы [ 7 ]

33 голосов
/ 28 июня 2009

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

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

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

[EDIT]

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

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

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

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

Этот поток содержит конкретный пример с методами Start, Pause, Resume и Stop. Обратите внимание, что пример Браннона никогда не прерывает поток. Он только инициирует событие, а затем ждет, пока поток не завершит изящное завершение.

17 голосов
/ 28 июня 2009

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

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

7 голосов
/ 28 июня 2009

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

2 голосов
/ 28 июня 2009

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

0 голосов
/ 12 февраля 2011

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

0 голосов
/ 28 июня 2009

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

0 голосов
/ 28 июня 2009

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

Это позволит вам остановить обработку на некоторое время, а затем возобновить.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...