线程已退出,code 0在Windows窗体窗体、线程、code、Windows

2023-09-04 11:07:36 作者:▲胡思乱想是我的作风i

我有问题,退出线程在我的Windows窗体。

I have problem with exiting threads in my Windows Forms.

我有经典的Windows窗体,它正在运行。我需要做一些事情的每一段时间,所以我说:

I have classic Windows Forms, which is running. I need to do something every period of time, so I added:

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的被称为线程数(主线程和定时器),所以我介绍了这种方式:

Method DoSomething is called by few threads (main thread and this timer), so I covered it that way:

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);
                } 
            }
        }

和一切运作良好,直到我的计时器线程只是退出与消息:

And everything works good, until my timer thread just exits with message:

The thread 0x2798 has exited with code 0 (0x0).

同样的事情发生在我的FileSystemWatcher的,这也叫DoSomething的方法。 这两个事件是独立的,出口在随机时间(至少我没有发现它的任何规则)

Same thing happens to my FileSystemWatcher, which also calls DoSomething Method. Both events are independent and exit at random time (at least I did not find any rule for it)

是什么原因导致这种情况,并哪能prevent呢?

What causes this situation and how can I prevent it?

推荐答案

如果你不保持一个参考定时器对象,这将是垃圾收集。

If you don't keep a reference to the timer object, it will be garbage collected.

看着你已经张贴了code,它不会出现要保持保持基准的。你需要使它成为一个领域的包含类,而不是一个局部变量。

Looking at the code that you've posted, it doesn't appear that you are keeping hold of the reference. You will need to make it a field in your containing class, rather than a local variable.

定时器还可以得到垃圾回收,如果你在一个长期运行的方法开始申报,并没有后来引用它的方法。

The timer can also get garbage collected if you declare it at the start of a long-running method and don't reference it later in the method.

您可以通过添加 GC.KeepAlive(定时器)解决特定的问题; 附近的方法的这里描述。

You can fix that particular problem by adding GC.KeepAlive(timer); near the end of the method as described here.