如何取消线程?

对于BackgroundWorker ,可以通过DoWorke.Cancel属性报告取消 – 事件处理程序。

如何使用Thread对象实现相同的function?

以下是一种完成此方法的示例。

 private static bool _runThread; private static object _runThreadLock = new object(); private static void Main(string[] args) { _runThread = true; Thread t = new Thread(() => { Console.WriteLine("Starting thread..."); bool _localRunThread = true; while (_localRunThread) { Console.WriteLine("Working..."); Thread.Sleep(1000); lock (_runThreadLock) { _localRunThread = _runThread; } } Console.WriteLine("Exiting thread..."); }); t.Start(); // wait for any key press, and then exit the app Console.ReadKey(); // tell the thread to stop lock (_runThreadLock) { _runThread = false; } // wait for the thread to finish t.Join(); Console.WriteLine("All done."); } 

简而言之; 线程检查bool标志,并在标志为true继续运行。 我更喜欢这种方法而不是调用Thread.Abort因为它似乎更好,更清洁。

通常,您通过线程的执行作为对象上的方法的委托来执行此操作,该对象公开Cancel属性,并且长时间运行的操作定期为tru确定是否退出该属性。

例如

 public class MyLongTunningTask { public MyLongRunninTask() {} public volatile bool Cancel {get; set; } public void ExecuteLongRunningTask() { while(!this.Cancel) { // Do something long running. // you may still like to check Cancel periodically and exit gracefully if its true } } } 

其他地方:

 var longRunning = new MyLongTunningTask(); Thread myThread = new Thread(new ThreadStart(longRunning.ExecuteLongRunningTask)); myThread.Start(); // somewhere else longRunning.Cancel = true; 

可以通过以下两种方式之一提前停止阻塞的线程:

  • 了Thread.interrupt

  • Thread.Abort的

主要问题是,如果线程适用于需要正确释放的任何ressource – 在这种情况下 – 您需要使用运行该线程的实际对象的属性。

Thread.Abort ,它通过将ThreadAbortException注入线程来工作。 这有点冒险,因为:

  1. 如果当时正在执行本机代码,您的线程可能会卡住
  2. 线程中的代码最好是exception安全的,因为这个ThreadAbortException可能发生在它内部的任何代码行上,甚至像i = i + 1那样无辜的东西

你最好在GUI线程和后台线程之间编写自己的信号机制。 很难在不知道该线程内部发生什么的情况下推荐一些东西,但是我有一个通过等待循环中的某个对象工作的线程,我使用AutoResetEvent并等待它。