2015-07-27 1 views
2

Я хочу, когда я нажму кнопку thread.Abort() и завершу печать печати после того, как он прервется. Он только прерывает поток при завершении текущего задания. БлагодаряКак прервать поток, когда текущее задание в потоке завершено C#

namespace ThreadTest 
{ 
public partial class Form1 : Form 
{ 
    Thread thread; 
    bool loop = true; 
    Stopwatch regularSW = new Stopwatch(); 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     thread = new Thread(new ThreadStart(() => threadtest())); 
     thread.Start(); 
    } 
    private void button2_Click(object sender, EventArgs e) 
    { 
     thread.Abort(); 
    } 
    public void threadtest() 
    { 
     while (loop) 
     { 
      regularSW.Start(); 
      Thread.Sleep(5000); 
      regularSW.Stop(); 
      this.Invoke(new Action(() => label1.Text += "Sleep in: " + regularSW.Elapsed + Environment.NewLine)); 
     } 
    } 
} 

}

ответ

5

Thread.Abortявляется запрос, операционная система и поток вольны игнорировать его в ситуациях, когда прерывания не представляется возможным. Как правило, Abort никогда не следует использовать в сценариях «по дизайну». Вместо этого, ваш цикл должен проверить, есть ли отменить действие в ожидании, возможно, что-то вроде этого:

Thread thread; 
bool loop = true; 
volatile bool _cancelPending = false; 
Stopwatch regularSW = new Stopwatch(); 
//Snip... unchanged code removed for brevity. 
private void button2_Click(object sender, EventArgs e) 
{ 
    _cancelPending = true; 
} 
public void threadtest() 
{ 
    while (loop) 
    { 
     if (_cancelPending) break; 
     regularSW.Start(); 
     Thread.Sleep(5000); 
     regularSW.Stop(); 
     this.Invoke(new Action(() => label1.Text += "Sleep in: " + regularSW.Elapsed + Environment.NewLine)); 
    } 
} 

Возможно, это цель вашего loop поля, но я ввел еще одно поле, _cancelPending, в-случае служит другой цели.

+0

Этого ответ требует от вас ждать потока просыпаться, прежде чем аннулирование фактически продолжается; обычно не желаемое поведение. –

2

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

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

Тем не менее, наибольшая обеспокоенность вызывает то, что Ваша тема проводит большую часть времени, спать. Это означает, что когда нажата кнопка «Отмена», вы должны дождаться, когда поток проснется, прежде чем он заметит, что была запрошена отмена.

Мы можем использовать механизм отмены для имитации резьбы спать, имея его ждать в течение периода времени, или для отмены быть запрошена - в зависимости от того происходит первое:

Thread thread; 
CancellationTokenSource cts; 
Stopwatch regularSW = new Stopwatch(); 
public Form1() 
{ 
    InitializeComponent(); 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    cts = new CancellationTokenSource(); 
    thread = new Thread(new ThreadStart(() => threadtest(cts.Token))); 
    thread.Start(); 
} 
private void button2_Click(object sender, EventArgs e) 
{ 
    cts.Cancel(); 
} 
public void threadtest(CancellationToken cancellation) 
{ 
    while (!cancellation.IsCancellationRequested) 
    { 
     regularSW.Start(); 

     // Simulate a Thread.Sleep; returns true if cancellation requested. 
     if (!cancellation.WaitHandle.WaitOne(5000)) 
     { 
      regularSW.Stop(); 
      this.Invoke(() => label1.Text += "Sleep in: " 
       + regularSW.Elapsed 
       + Environment.NewLine); 
     } 
    } 
}