线程过早停止
本文关键字:线程 | 更新日期: 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类中执行几个函数:
- 构造器cDownloader(),它设置了几个变量。
- 构造函数触发initLoad(),它会初始化一个计时器,并为它添加一个事件。
- 计时器滴答事件扫描一个网站与HtmlAgilityPack类fileththumb链接。
- 对于每个链接,事件创建一个新的线程来下载文件。
不知何故,线程似乎激活一切,甚至下载文件,然后关闭自己,同时仍然运行定时器,这是奇怪的,因此它会导致一个错误,因为当前线程无法找到。
我没有在当前线程上调用.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线程。