1

不知何故,我的线程过早停止,而它应该一直处于活动状态,直到状态变为 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 扫描网站,以查找具有类 fileThumb 的链接。
  4. 对于每个链接,该事件都会创建一个下载文件的新线程。

不知何故,该线程似乎激活了一切,甚至下载了文件,然后自行关闭,同时仍在运行计时器,这很奇怪,因此由于找不到当前线程而导致错误。

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

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

4

3 回答 3

3

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

于 2013-04-01T15:59:36.070 回答
3

部分问题是以下行

Name = this.textBox1.Text;

UI 不能从后台线程访问,会抛出异常。因此,在cDownloader创建类并随后杀死线程之后,这条线被抛出。您需要将 UI 访问移出后台线程或将访问适当地编组回 UI 线程。

于 2013-04-01T15:59:41.467 回答
3

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

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在该上下文之外很有用。

于 2013-04-01T16:03:11.713 回答