如何在线程中的当前作业完成时中止线程
本文关键字:线程 作业 完成时 | 更新日期: 2023-09-27 18:04:48
我想当我点击thread. abort()和线程完成打印标签之后,它将中止。它只在完成当前任务时中止线程。由于
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));
}
}
}
}
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
,以防它服务于不同的目的。
终止线程在大多数应用程序中都不应该这样做;当线程不再有工作要做时,它将作为其生命周期的一个自然部分而停止。
要允许这种情况发生,您的代码需要发出该方法应该停止执行的信号。在。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);
}
}
}