【问题标题】:Restarting a thread in .NET (using C#)在 .NET 中重新启动线程(使用 C#)
【发布时间】:2009-06-28 13:04:09
【问题描述】:

我正在寻找一种方法来重新启动已被 Abort() 停止的线程..

public partial class MyProgram : Form
{
  private Thread MyThread = new Thread(MyFunction);
  private System.Windows.Forms.Button startStopBtn = new System.Windows.Forms.Button();
  public MyProgram()
  {
    MyThread.Start();
    startStopBtn += new EventHandler(doStop);
    startStopBtn.Text = "Stop";
  }
  private static void MyFunction()
  {
    // do something
  }
  private void doStop(object sender, EventArgs e)
  {
    MyThread.Abort();
    startStopBtn -= new EventHandler(doStop);
    startStopBtn += new EventHandler(doStart);
    startStopBtn.Text = "Start";
  }
  private void doStart(object sender, EventArgs e)
  {
    MyThread.Start(); // << Error returned when clicking the button for 2nd time
    startStopBtn -= new EventHandler(doStart);
    startStopBtn += new EventHandler(doStop);
    startStopBtn.Text = "Stop";
  }
}

有什么想法吗?

【问题讨论】:

    标签: c# multithreading


    【解决方案1】:

    一旦中止线程,就无法再次启动它。

    但您的实际问题是您正在中止您的线程。你应该never use Thread.Abort()

    如果您的线程应该暂停并继续多次,您应该考虑使用其他机制(例如AutoResetEvent)。

    [编辑]

    如上面链接中的Ian Griffiths 所述,中止线程的最简单解决方案是:

    我一直推荐的方法非常简单。有一个 volatile bool 字段,对您的工作线程和 UI 线程都可见。如果用户点击取消,设置这个标志。同时,在您的工作线程上,不时测试该标志。如果你看到它被设置,停止你正在做的事情。

    要使其正常工作,您唯一需要做的就是重新安排后台方法,使其循环运行 - 这样您就可以定期检查您的标志是否已设置由不同的线程。

    如果您需要为同一个工作线程提供暂停和恢复功能,而不是简单的volatile bool 标志方法,您可以采用稍微复杂一点的方法,例如AutoResetEvent 的同步结构。这些类还提供了一种方法,使工作线程在来自非工作线程的信号之间休眠一段指定(或无限期)的时间。

    This thread 包含一个带有 Start、Pause、Resume 和 Stop 方法的具体示例。请注意 Brannon 的示例 never 如何中止线程。它只触发一个事件,然后等待线程优雅地结束。

    【讨论】:

      【解决方案2】:

      doStart() 中调用MyThread.Start() 之前只需添加MyThread = new Thread(MyFunction)。不要在你的方法之外创建线程,那里是声明的空间。

      请注意,使用 thread.Abort() 终止线程可能非常危险,因为它可能会导致 unexpected behavior 或可能无法正确处置线程拥有的资源。您应该尝试完成干净的多线程,如 his answer 中描述的 Groo。

      【讨论】:

      • 这个答案更像是一种解决方法而不是真正的答案。你甚至没有解释他为什么会出错。 Groo 做对了。
      • 你是对的,但是当我还是一个编程初学者时,我遇到了几个类似的问题。我从 groo 阅读了许多类似的解决方案,是的,你完全正确,我的解决方案只是一种解决方法。但是 groo 描述的机制对我来说太复杂了,以至于在我的编程新手时代无法理解。所以我认为,为经验不足的程序员提供一个简单的“答案”(或解决方法)可能会更好。
      • 这是让程序员很差的东西。他们没有投入足够的时间来了解他们在做什么。你走后谁来收拾你的 Thread.Abort 烂摊子?
      【解决方案3】:

      简单的答案是,你不能。一旦线程被中止,您就无法重新启动它。只需创建一个方法或其他东西,它会根据您的需要返回一个 Thread 对象。当您需要一个新线程时,只需从该方法中获取即可。

      【讨论】:

        【解决方案4】:

        不,没有,但您为什么要这样做?只需启动一个新线程,使用相同的 ThreadStart 和相同的参数(如果有)。

        【讨论】:

          【解决方案5】:

          如果确实需要中断线程函数并恢复,则应该设置一个条件,然后在处理过程中定期检查。

          这将允许您停止处理一段时间然后恢复。

          我使用事件和等待调用来完成类似的任务。

          【讨论】:

            【解决方案6】:

            最简单的方法是不中止线程。

            【讨论】:

              【解决方案7】:

              我真的不明白为什么人们在不知道正确的情况下提供信息.. 真正的程序员如何暂停或停止处理线程一段时间然后释放它,从而使代码易受攻击...... @Brad--对不起..但你的想法不好.. @Rhythmic - 你需要按照自己的方式处理事情..

              如果你们以他想说的同样方式得到他,BFree 是对的。 你只需要重新声明..

              下面是例子:

              Public Shared Sub ResetAbort()
              
                  Dim ThreadPleaseWait As New Thread(New ThreadStart(AddressOf YourSubName))
              
                  YourThreadName.Start()
              
                  Thread.Sleep(2000)
              
                  YourThreadName.Abort()
              
              End Sub
              

              现在你可以在任何你想启动线程的地方使用这个 Sub。它会自动中止线程。

              如果您想在 Button1_click() 事件上启动线程并在 Button2_Click() 事件上停止它,请使用:

              在 Button1_click() 事件中

                  Dim ThreadPleaseWait As New Thread(New ThreadStart(AddressOf YourSubName))
              
                  YourThreadName.Start()
              

              在 Button2_click() 事件中

                  YourThreadName.Start()
              

              这样做你会在你想要的任何地方中止你的线程并再次初始化它。 您还可以使用 YourThreadName.ThreadState.Running 属性来检查线程是否正在运行(只是为了避免同一线程的多个实例.....

              【讨论】:

              • 请修正您的格式。此外,在编辑它时,您可能希望使其不那么好战。虽然您不喜欢“不”这个词,但您无法重新启动已中止的线程。 OP要求的内容是不可能的。此外, Thread.Abort() 被认为是有害的。有更好的方法来控制线程执行。你不会通过让他继续做坏事来服务提问者。最好提供满足他要求的替代方案,而不会产生同样的风险。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2015-06-23
              • 1970-01-01
              • 1970-01-01
              • 2011-01-05
              • 1970-01-01
              • 1970-01-01
              • 2021-11-06
              相关资源
              最近更新 更多