C# 线程已在Windows窗体中退出,代码为0
我在Windows窗体中退出线程时遇到问题 我有经典的Windows窗体,它正在运行。我每段时间都需要做一些事情,所以我补充道:C# 线程已在Windows窗体中退出,代码为0,c#,.net,multithreading,winforms,C#,.net,Multithreading,Winforms,我在Windows窗体中退出线程时遇到问题 我有经典的Windows窗体,它正在运行。我每段时间都需要做一些事情,所以我补充道: TimerCallback timerDelegate = new TimerCallback(this.TryDoSomething); int period = 10 * 1000; // to miliseconds System.Threading.Timer stateTimer = new System.Threading.Timer(timerDeleg
TimerCallback timerDelegate = new TimerCallback(this.TryDoSomething);
int period = 10 * 1000; // to miliseconds
System.Threading.Timer stateTimer = new System.Threading.Timer(timerDelegate, null, period, period);
方法DoSomething由几个线程(主线程和这个计时器)调用,因此我以这种方式介绍了它:
private void TryDoSomething(object o)
{
lock (tryDoSomethingMutex)
{
if (this.dataGridView1.InvokeRequired)
{
RefreshCallback d = new RefreshCallback(DoSomething);
this.Invoke(d, new object[] { o });
}
else
{
this.DoSomething(o);
}
}
}
一切正常,直到我的计时器线程带着消息退出:
The thread 0x2798 has exited with code 0 (0x0).
同样的事情也发生在我的FileSystemWatcher上,它也调用DoSomething方法。
这两个事件都是独立的,在随机时间退出(至少我没有找到任何规则)
造成这种情况的原因是什么?我如何防止它?听起来计时器正在被垃圾收集。将其作为表单的实例变量,以便保留引用。如果不保留对计时器对象的引用,它将被垃圾收集 查看您发布的代码,您似乎没有保留引用。您需要将其设置为包含类中的字段,而不是局部变量 如果在长时间运行的方法开始时声明计时器,并且以后在方法中不引用它,则计时器也可能被垃圾回收
您可以通过添加
GC.KeepAlive(计时器)来解决这个特定问题代码>接近方法结尾。这不是错误,它只是指示线程已完成执行。直到线程退出为止?所以这不是为了退出?你不是设定决斗时间的人吗?这就是问题所在——我不是。定时器被设置为在每一段时间内做一些事情,并突然在随机时间内退出(但没有任何错误)。当然这是正确的答案,谢谢!现在,当我想到这一点时,它似乎很明显。误导我的是,当声明线程的方法在“很久”以前结束时,线程通常要花一分钟以上的时间才能退出。所以垃圾收集器花了大约一分钟(有时甚至两分钟或更长时间)才发现它是垃圾,应该被处理掉?为什么这么长时间?除非内存越来越低,否则垃圾收集器通常不会经常运行,以减少开销;我想这就是为什么花了这么长时间。这是有道理的。谢谢:)为了完全准确,我真的应该说“第2代垃圾收集往往不会经常运行”。第0代会频繁运行,但计时器可能会保留到第2代。