2009-06-28 4 views
10

Я ищу способ, чтобы перезапустить поток, который был остановлен Abort() ..Перезапуск поток в .NET (с использованием C#)

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

Любая идея?

ответ

12

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

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

+0

Этот ответ скорее обходным решением, чем реальным ответом. даже не объясняю, почему он ошибается. У меня получилось правильно. – Trap

+3

Вы правы, но когда я был новичком в программировании, у меня было несколько подобных проблем. Я читал много решений, подобных этому из groo, и да, вы совершенно правы, мое решение - всего лишь обходное решение. Но механизмы, которые описывают groo, были слишком сложны для меня, чтобы понять в моем программировании-newb раз. Так что, я бы мог лучше дать простой «ответ» (или обходной путь) для программиста, который не так опытен. – Emiswelt

+0

Это то, что делает плохих программистов. Они не вкладывают достаточно времени, чтобы понять, что они делают. o собирается очистить ваш Thread.Abort беспорядок, когда вы ушли? –

2

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

6

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

29

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

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

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

[EDIT]

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

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

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

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

This thread содержит конкретный пример с использованием методов «Старт», «Пауза», «Продолжить» и «Остановить». Обратите внимание, что пример Браннона никогда отменяет нить. Он только запускает событие, а затем ждет, пока поток не закончится изящно.

0

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

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

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

0

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

-3

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

+5

Исправьте свое форматирование. Кроме того, пока вы редактируете его, вы можете сделать его немного менее воинственным. В то время как вам не нравится слово «нет», вы не можете перезапустить прерванный нить *. То, что задает ОП, невозможно. Кроме того, Thread.Abort() считается вредным. Есть гораздо лучшие способы контроля выполнения потоков. Вы не служите аскеру, позволяя ему продолжать делать плохие вещи. Лучше дать альтернативы, которые отвечают его требованиям, не подвергая себя одному и тому же риску. – Will

Смежные вопросы