【问题标题】:Stop C# thread immediately without "Thread.Abort()"在没有“Thread.Abort()”的情况下立即停止 C# 线程
【发布时间】:2021-12-17 12:48:31
【问题描述】:
public class Worker
{
    private CancellationTokenSource cts;
    private Thread t;

    public Worker()
    {
        cts = new CancellationTokenSource();
        t = new Thread(() => { ThreadTask(cts.Token); });
    }

    ~Worker()
    {
        cts.Dispose();
    }

    private void ThreadTask(CancellationToken ct)
    {
        try
        {
            while (true)
            {
                if (ct.IsCancellationRequested)
                {
                    Debug.WriteLine("Cancelllation requested");
                    break;
                }

                // long task 1
                Debug.WriteLine("Task 1 completed");
                Thread.Sleep(2000);
                // long task 2
                Debug.WriteLine("Task 2 completed");
                Thread.Sleep(2000);
                // long task 3
                Debug.WriteLine("Task 3 completed");
                Thread.Sleep(2000);
                // long task 4
                Debug.WriteLine("Task 4 completed");
                Thread.Sleep(2000);
                Debug.WriteLine("All tasks completed");
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Thread exception: " + ex.ToString());
        }
        finally
        {
            // cleanup
            Debug.WriteLine("Thread cleanup");
        }
    }

    public void Start()
    {
        t.Start();
    }

    public void Stop()
    {
        cts.Cancel();
    }
}

我想知道是否可以在线程完成执行之前中断它。

例如,在上面描述的代码中,当调用函数Stop()时,线程将在执行完成后停止,我想更快地停止它,例如在“长任务”之间甚至在@ 987654324@.

解决方案是在调用Stop() 时可能会在任务线程中抛出异常,例如Thread.Abort(),但Thread.Abort() 在Net 6.0 上不起作用,我该怎么做?

环境:

  • C#
  • 网络 6.0
  • Windows 10 x64
  • Visual Studio 2019 和 Visual Studio 2022

【问题讨论】:

  • 您应该切换到异步方法并使用await Task.Delay(2000, ct);。但是,没有简单的方法可以停止 CPU 密集型任务。该任务需要定期检查是否取消。
  • 看看there。否则(AFAIK)你需要在任务之间实现某种合作(取消令牌、协程......)
  • Thread.Abort() 可用时,它不能解决您的问题。调用 Abort 仅在您尝试强制退出应用程序时有用,因为调用它可能会破坏 .NET 运行时本身。调用Abort 后,您不能依赖您的程序正常工作。唯一真正的答案是让线程合作停止。
  • 感谢所有 cmets。 @JeremyLakeman 你的建议很有帮助,即使没有 Task.Delay(2000, ct).Wait() 的异步方法,我什至设法使用它。
  • @PedroDuarte - 请不要.Wait() 处理此类任务。您应该始终使用await

标签: c# .net multithreading abort


【解决方案1】:

您可以使用Thread.Interrupt 方法。当前 .NET 平台支持此 API。

中断处于WaitSleepJoin 线程状态的线程。

如果该线程当前没有被阻塞在等待、睡眠或加入状态,它将在下一次开始阻塞时被中断。

ThreadInterruptedException 在被中断的线程中抛出,但直到线程阻塞。如果线程从不阻塞,则永远不会抛出异常,因此线程可能会在不被中断的情况下完成。

您必须在ThreadStart 委托的主体内处理可能的ThreadInterruptedException,否则在调用Interrupt 时进程可能会崩溃。或者您可以使用通用的 catch (Exception) 处理程序来处理所有异常,就像您目前正在做的那样。

【讨论】:

  • 使用Thread.Interrupt() 是一个非常好的选择,感谢您的建议。
猜你喜欢
  • 2014-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 2015-10-09
  • 1970-01-01
  • 2022-07-04
相关资源
最近更新 更多