簡體   English   中英

當線程中的當前作業完成c#時如何中止線程

[英]How to abort thread when current job in thread complete c#

我希望當我點擊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);
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM