终止 .NET 线程

发布于 2024-07-26 09:22:46 字数 109 浏览 8 评论 0原文

我创建了一个运行特定方法的线程。 但有时我想杀死该线程,即使它仍在工作。 我怎样才能做到这一点? 我尝试了 Thread.Abort() 但它显示了一个消息框,显示“线程已中止”。 我应该怎么办?

I have created a thread running a certain method. But sometimes I would like to kill the thread even if it is still working. How can I do this? I tried Thread.Abort() but it shows up a messagebox saying "Thread aborted". What should I do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

╄→承喏 2024-08-02 09:22:46

不要调用Thread.Abort()

Thread.Abort 是危险的。 相反,您应该与线程合作,以便它可以和平地关闭。 需要设计线程,以便可以告诉它自行终止,例如,当您希望线程停止时,可以将布尔 keepGoing 标志设置为 false。 然后,线程将具有类似的内容:

while (keepGoing)
{
    /* Do work. */
}

如果线程可能会在 SleepWait 中阻塞,那么您可以通过调用 Thread.Interrupt()。 然后线程应该准备好处理 ThreadInterruptedException:

try
{
    while (keepGoing)
    {
        /* Do work. */
    }
}
catch (ThreadInterruptedException exception)
{
    /* Clean up. */
}

Do not call Thread.Abort()!

Thread.Abort is dangerous. Instead you should cooperate with the thread so that it can be peacefully shut down. The thread needs to be designed so that it can be told to kill itself, for instance by having a boolean keepGoing flag that you set to false when you want the thread to stop. The thread would then have something like

while (keepGoing)
{
    /* Do work. */
}

If the thread may block in a Sleep or Wait then you can break it out of those functions by calling Thread.Interrupt(). The thread should then be prepared to handle a ThreadInterruptedException:

try
{
    while (keepGoing)
    {
        /* Do work. */
    }
}
catch (ThreadInterruptedException exception)
{
    /* Clean up. */
}
翻身的咸鱼 2024-08-02 09:22:46

您实际上应该仅将调用 Abort() 作为最后的手段。 您可以使用变量来同步此线程:

volatile bool shutdown = false;

void RunThread()
{
   while (!shutdown)
   {
      ...
   }
}

void StopThread()
{
   shutdown = true;
}

这允许您的线程干净地完成它正在做的事情,使您的应用程序处于已知的良好状态。

You should really only call Abort() as a last resort. You can use a variable to sync this thread instead:

volatile bool shutdown = false;

void RunThread()
{
   while (!shutdown)
   {
      ...
   }
}

void StopThread()
{
   shutdown = true;
}

This allows your thread to cleanly finish what it was doing, leaving your app in a known good state.

_蜘蛛 2024-08-02 09:22:46

最正确且线程安全的方法是使用 WaitHandle 在线程应该停止时向其发出信号。 我主要使用ManualResetEvent。

在您的线程中,您可以:

private void RunThread()
{
    while(!this.flag.WaitOne(TimeSpan.FromMilliseconds(100)))
    {
        // ...
    }
}

其中 this.flag 是 ManualResetEvent 的实例。 这意味着您可以从线程外部调用 this.flag.Set() 来停止循环。

仅当设置该标志时,WaitOne 方法才会返回 true。 否则,它将在指定的超时(示例中为 100 毫秒)后超时,并且线程将再次运行循环。

The most correct and thread-safe way is to use a WaitHandle to signal to the thread when it's supposed to stop. I mostly use ManualResetEvent.

In your thread, you can have:

private void RunThread()
{
    while(!this.flag.WaitOne(TimeSpan.FromMilliseconds(100)))
    {
        // ...
    }
}

where this.flag is an instance of ManualResetEvent. This means that you can call this.flag.Set() from outside the thread to stop the loop.

The WaitOne method will only return true when the flag is set. Otherwise, it will time out after the specified timeout (100 ms in the example) and the thread will run through the loop once more.

笑饮青盏花 2024-08-02 09:22:46

杀死一个线程并不是一个好主意。 最好是发出信号,让事情停止,让它优雅地结束。 有多种不同的方法可以做到这一点。

  • 如果它被阻塞,使用 Thread.Interrupt 来戳它。
  • 轮询标志变量。
  • 使用 WaitHandle 类发送信号。

我不需要重新讨论如何使用每种方法,因为我已经在 这个答案

It is not a good idea to kill a thread. It is better to signal that it should stop and let it end gracefully. There are various different ways of doing this.

  • Use Thread.Interrupt to poke it if it is blocked.
  • Poll a flag variable.
  • Use the WaitHandle class to send a signal.

There is no need for me to rehash how each method can be used since I have already done so in this answer.

我早已燃尽 2024-08-02 09:22:46

中止线程是一个非常糟糕的主意,因为您无法确定线程在中止时正在做什么。

相反,拥有一个线程可以检查并且外部代码可以设置的属性。 让线程在安全退出时检查此布尔属性。

Aborting a thread is a very bad idea, since you cannot determine what the thread was doing at the time of the abort.

Instead, have a property that the thread can check, and that your external code can set. Let the thread check this boolean property when it's at a safe place to exit.

怪我鬧 2024-08-02 09:22:46

我同意乔恩·B

volatile bool shutdown = false;

void RunThread()
{

try
{
    while (!shutdown)
    {
        /* Do work. */
    }
}
catch (ThreadAbortException exception)
{
    /* Clean up. */
}
}

void StopThread()
{
   shutdown = true;
}

I agree to Jon B

volatile bool shutdown = false;

void RunThread()
{

try
{
    while (!shutdown)
    {
        /* Do work. */
    }
}
catch (ThreadAbortException exception)
{
    /* Clean up. */
}
}

void StopThread()
{
   shutdown = true;
}
金兰素衣 2024-08-02 09:22:46

我的 WebServer 类中还有杀死线程的示例...

https://net7ntcip .codeplex.com/SourceControl/changeset/view/89621#1752948

我想说,中止是可以的,只需了解后果是什么...只要您在长时间运行的任务之前指示状态,中止将起作用,但标志是必需的,例如(ShouldStop 或 ActionBranch 等)

查看示例!

There are also examples of killing threads in my WebServer class...

https://net7ntcip.codeplex.com/SourceControl/changeset/view/89621#1752948

I would say Abort is okay just understand what the ramifications are... as long as you are indicating state before a long running task Abort will work but flags are required such as (ShouldStop or ActionBranch etc)

Check it out for examples!

你列表最软的妹 2024-08-02 09:22:46

编辑:

  1. 我为此创建了一个小类

  2. 注意到它不适用于 async/await

  3. 发布了对类的更新,然后 Theodor Zoulias(谢谢:))让我知道这个想法是有缺陷的。

  4. 现在我重新发布原始类(不适用于 async/await!)

    var t = new StopAbleThread(isShutDown =>; 
       { 
         Console.WriteLine("a"); 
         while (!isShutDown()) 
         { 
           Console.WriteLine("b"); 
           Thread.Sleep(TimeSpan.FromMinutes(10)); 
         } 
       } )    
    
      { 背景 = true }; 
         t.Start(); 
      

像这样停止线程:

t.Stop();

类:

public class StopAbleThread
{
  public bool IsBackground
  {
    set => _thread.IsBackground = value;
  }

  private readonly Thread _thread;
  private volatile bool _shutdown;

  public delegate bool IsShutDown( );
  public delegate void CodeToRun( IsShutDown isShutDown );


  public StopAbleThread( CodeToRun codeToRun )
  {
    _thread = new Thread( ( ) =>
    {
      try
      {
        codeToRun( _IsShutDown );
      }
      catch( ThreadInterruptedException )
      {
        //ignore
      }
    } );
  }

  private bool _IsShutDown( )
  {
    return _shutdown;
  }

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

  public void Stop( )
  {
    _shutdown = true;
    _thread.Interrupt( );
  }
}

Edit:

  1. I created a little class for this

  2. Noticed it didn't work with async/await

  3. Posted an update to the class, then Theodor Zoulias (thanks :)) let me know this idea was flawed.

  4. Now I'm reposting the original class (doesn't work with async/await!)

    var t = new StopAbleThread(isShutDown =>
     {
       Console.WriteLine("a");
       while (!isShutDown())
       {
         Console.WriteLine("b");
         Thread.Sleep(TimeSpan.FromMinutes(10));
       }
     }  )   
    
    { IsBackground = true };
       t.Start( );
    

Stop the thread like this:

t.Stop();

The class:

public class StopAbleThread
{
  public bool IsBackground
  {
    set => _thread.IsBackground = value;
  }

  private readonly Thread _thread;
  private volatile bool _shutdown;

  public delegate bool IsShutDown( );
  public delegate void CodeToRun( IsShutDown isShutDown );


  public StopAbleThread( CodeToRun codeToRun )
  {
    _thread = new Thread( ( ) =>
    {
      try
      {
        codeToRun( _IsShutDown );
      }
      catch( ThreadInterruptedException )
      {
        //ignore
      }
    } );
  }

  private bool _IsShutDown( )
  {
    return _shutdown;
  }

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

  public void Stop( )
  {
    _shutdown = true;
    _thread.Interrupt( );
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文