停止线程的最佳方法

时间:2014-05-04 21:05:54

标签: c# multithreading

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

好吧,所以我需要停止线程,以便它不会继续。我听说'Abort'不是一个好的解决方案,我应该制作一个标志变量并进行查询,但我应该怎么做呢? 有没有更好的方法? 如果您需要代码,请告诉我,但这是一个更普遍的问题。

谢谢!

4 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

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

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

(但是,当然,您还应该记住,如果线程以某种方式与表单交互,那么您需要处理它,否则关闭表单可能会导致线程中的异常,当它不再能够访问被处置物品等。)

答案 2 :(得分:1)

你必须确保你的线程正确执行并清理干净。在此之后,您可以关闭表单并删除线程对象。

这就是我通常处理所有线程的方式。我使用了一堆“信号”变量(我在他们自己的类中定义)允许我控制我的线程并从应用程序线程检查它的状态。如果你试着去捕捉一些东西,那就太棒了!只是“中止”该功能完全掉落直到其空闲运行。线程完成后,您可以安全地删除它。

    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之后再删除它。

我希望这会有所帮助。

答案 3 :(得分:1)

好吧,我设法做到了,任务实际上非常简单。

您必须为要执行的void /函数声明 CancellationTokenSource Action 。 像那样:

CancellationTokenSource cancellationToken = new CancellationTokenSource();
Action yourAction;

然后使用void执行初始化操作:

yourAction = anyvoid;

最后:

yourAction.BeginInvoke(yourAction.EndInvoke, null); 

这就是你如何开始的。 现在,当你需要取消/停止线程时,你继续说:

cancellationToken.Cancel();

之后它将取消该线程。 为了避免在此期间线程正在进行,只需在所有“取消”执行后进行查询。

if (cancellationToken.IsCancellationRequested)
  return;

就是这样。优点是,您不必处理任何AbortExceptions或任何东西,这是一种停止线程的简洁方法。