停止线程的最好方法

本文关键字:方法 线程 | 更新日期: 2023-09-27 18:01:33

我正在使用线程池中的线程来执行一些操作。现在,在某些情况下,如果出现问题,我想要关闭表单。我有一个try/catch块,如果它捕获了一些东西,它应该做一些事情,然后关闭表单。问题是,当关闭时,线程在后台继续运行,然后在我调用某些内容的地方抛出异常,因为句柄不再存在。

那么,我需要停止线程,这样它就不会继续了。我听说"中止"不是一个很好的解决方案,好吧,我应该做一个标志变量和查询,但我应该怎么做呢?有没有更好的办法?如果您需要代码,请告诉我,但这是一个更普遍的问题。

谢谢!

停止线程的最好方法

我不确定是什么问题,因为你没有提供代码,但也许你应该检查invokerrequiredproperty,试试这个:

if (Control.InvokeRequired)
{
// your code
}

我通常有一个标志设置为true当窗体关闭时,或者当我需要线程终止任何其他原因

另一个有用的事情是将IsBackground属性设置为true,这使得进程在最后一个表单关闭时终止,而不是留下一个运行的幽灵进程。

例如,如果你有一个表单生成一个线程,该线程定期在while (true)中进行计算,你必须在表单关闭时以某种方式手动终止线程。如果您设置了IsBackground = true,那么线程将不会阻止进程终止。

(当然,您也应该记住,如果线程以某种方式与表单交互,那么您需要处理它,否则关闭表单可能会在线程中导致异常,当它不再能够访问已处置的对象时,等等)

你必须确保你的线程执行到最后正确和干净。在此之后,您可以关闭窗体并删除线程对象。

这就是我通常处理所有线程的方式。我使用一堆"信号"变量(我在它们自己的类中定义)来允许我控制我的线程并从应用程序线程检查它的状态。如果你试着抓住什么东西,那就太棒了!只要"中止"该函数,完全退出,直到其运行空闲。当线程完全结束后,你可以安全地删除它。

    void MyThreadFunction () {
      bThreadActive = true;
      while(!bThreadTerminate){
        bThreadIdle = false;  //thread is no longer idle.
        bThreadStart = false; //Reset this too 
        //Do all your thread stuff here.
          doSomething();
        while(!bThreadTerminate){
          //Stay here until we start or terminate
          bThreadIdle = true;
          if(bThreadStart)
            break;
        }
      }
      bThreadActive = false;
    }
    void doSomething(){
      //Anytime you go into a loop and if statements, check if it's been terminated.
      //When you set bThreadTerminate to true, exit the thread without any further calculations.
      //Any logical statement needs to also check if you want to terminate the thread.
      int iNum1 = 1;
      int iNum2 = 1;
      try {
        if(iNum1 == iNum2 && !bThreadTerminate){
        //Stuff to do.
        }
      }catch(Exception *e){
        //Abort Code here
      }
    }

基本上,这将执行一次所有操作,并等待直到您需要再次执行(在您的调用中)。将bStart设置为true,它将一直循环直到再次空闲。如果你将bThreadTerminate设置为true,那么在主线程上,你将等到bActive为false后再删除它。

嗯,我做到了,任务其实很简单。

你必须声明一个CancellationTokenSource和一个Action来执行void/函数。像这样:

CancellationTokenSource cancellationToken = new CancellationTokenSource();
Action yourAction;

然后用void初始化动作来执行:

yourAction = anyvoid;

最后:

yourAction.BeginInvoke(yourAction.EndInvoke, null); 

就是这样开始的。现在,当您需要取消/停止线程时,您可以继续输入:

cancellationToken.Cancel();

之后,它将取消线程。为了避免线程在这段时间内继续运行,只需在所有"Cancelling"执行之后查询即可。

if (cancellationToken.IsCancellationRequested)
  return;

就是这样。这样做的好处是,你不需要处理任何AbortExceptions或其他任何事情,这是一种停止线程的干净方式。