2013-04-17 47 views
4

我在Windows窗體中退出線程時遇到問題。線程在Windows窗體中用代碼0退出

我有經典的Windows窗體,它正在運行。我需要做一些事情每隔一段時間,所以我說:

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

一切工作不錯,直到我的timer線程只是消息退出:

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

同樣的事情發生到我的FileSystemWatcher的,這也叫DoSomething的方法。 這兩個事件是獨立的,隨機時間退出(至少我沒有找到任何規則)

什麼原因導致這種情況,我該如何防止它?

+0

它不是一個錯誤,它只是表明該線程已完成其執行。 –

+0

直到你的時間線程退出?所以它不是要退出?你不是適合時間的那個嗎? –

+0

這就是問題 - 我不是。定時器設置爲每一段時間都會執行某些操作,並且隨機時間突然退出(但沒有任何錯誤)。 –

回答

4

如果您不保留對定時器對象的引用,它將被垃圾回收。

查看您發佈的代碼,看起來您沒有保留參考。您需要將其設置爲包含類中的字段,而不是局部變量。

如果您在長時間運行的方法的開始處聲明該計時器,並且稍後未在方法中引用計時器,該計時器也可以收集垃圾回收。

您可以通過在方法as described here的末尾添加GC.KeepAlive(timer);來解決該特定問題。

+0

當然這是正確的答案,謝謝你!現在,當我思考這件事時,這似乎很明顯。導致我誤導的事實是,通常它花了一分鐘時間才退出,當時宣佈的方法在「很久以前」結束。所以它花了大約一分鐘(有時甚至兩個或更多)GarbageCollector發現它是垃圾,應該處置?爲什麼這麼久? –

+1

垃圾收集器往往不會經常運行,除非內存越來越少,以減少開銷;我期望這就是爲什麼花了這麼長時間。 –

+0

這使得sens。謝謝:) –

3

聽起來像計時器正在垃圾收集。使其成爲窗體的實例變量,以便您可以保留參考。