线程过早停止

本文关键字:线程 | 更新日期: 2023-09-27 18:06:45

不知何故,我的线程过早地停止了,而它应该一直是活的,直到状态变为4,或者线程通过.Abort()中止。

目前这是我如何开始我的线程:

var thread = new Thread(() =>
{
   var t = Thread.CurrentThread;
   var cDown = new cDownloader(textBox1, textBox3.Text, this, 10);
   updateThreads(t.ThreadState + ": " + t.Name, t);
 });
 thread.Start();

线程在cDownloader类中执行几个函数:

  1. 构造器cDownloader(),它设置了几个变量。
  2. 构造函数触发initLoad(),它会初始化一个计时器,并为它添加一个事件。
  3. 计时器滴答事件扫描一个网站与HtmlAgilityPack类fileththumb链接。
  4. 对于每个链接,事件创建一个新的线程来下载文件。

不知何故,线程似乎激活一切,甚至下载文件,然后关闭自己,同时仍然运行定时器,这是奇怪的,因此它会导致一个错误,因为当前线程无法找到。

我没有在当前线程上调用.Abort()方法。

所以我的问题是:为什么我的线程过早停止?

线程过早停止

看起来线程内部的任何东西实际上都没有阻塞。您可以使用退出标志,如下所示:

var exitRequested = false;
new Thread(
() => {
  var t = Thread.CurrentThread;
  var cDown = ...
  Name = textBox1.Text;
  updateThread(...);
  while(!exitRequested)
  {
    /// keep this thread from locking up a CPU core
    t.Sleep(10);
  }
}
).Start();

和,稍后当你想要线程退出(当应用程序关闭时,点击exit按钮等)

exitRequested=true;

循环是必要的,以防止线程提前退出。否则,当它到达lambda的末尾时,它会像其他方法一样返回。

还请注意,在线程中检查Thread.ThreadState通常会返回ThreadState.Running,因为为了执行线程方法中的任何代码,线程必须正在运行。ThreadState在该上下文中是有用的

线程将运行您传递给它的委托中的代码。一旦完成,线程将终止。除非updateThreads包含循环,否则线程将在完成委托中的最后一个方法调用时终止。

部分问题在于以下行

Name = this.textBox1.Text;

UI不能从后台线程访问,并且会抛出异常。因此,这一行是在创建cDownloader类之后抛出的,并随后杀死线程。您需要将UI访问移出后台线程,或者将访问适当地封送回UI线程。