2012-10-03 21 views
5

我在Compact Framework 2,SP2中使用C#。System.Threading.Timer無法啓動?

該設備的操作系統已設置爲啓動我的應用程序,我們稱之爲應用程序「Loader.exe」。

Loader就是這樣的:一個簡單的表單,如果需要的話,它會顯示狀態消息(如果有必要的話)(通俗的說法是指出現錯誤和異常消息,或者「啓動應用程序[xyz]」)和狀態機在顯示基本全屏窗體時在後臺運行。

所以裝載機的形式的構造函數在以下非常結束:

try 
{ 
    label1.Text = "Starting GUI Init Thread..."; //debug only message 
    System.Threading.Timer guiInit = new System.Threading.Timer(
     RunStateMachine, null, 2000, System.Threading.Timeout.Infinite 
     ); 
    //callback: RunStateMachine, null argument 
    //initial callback is 2000ms from this point, and doesn't run again. 
} 
catch (Exception ex1) 
{ 
    label1.Text = "GUI Init Error 2"; 
    Failure_Label.Text = ex1.Message; 
} 

和「RunStateMachine」確實在不同的線程比UI的工作,使形式顯示,並且任何時候RunStateMachine需求與表單交互,比如更新消息,我調用了一個函數,使用if(this.InvokeRequired){this.Invoke(...);} else {...}

所以,我的問題?
間歇性地,我的程序會掛起,這是因爲定時器沒有觸發回調。我在上面的try塊的調試消息中加入了許多其他地方,告訴我它掛起的位置,包括在「RunStateMachine」的非常開始處的消息。最後,我的程序掛在消息「Starting GUI Init Thread ...」

這告訴我,線程計時器沒有運行一個我需要它的時間。
我的理論是,它在定時器觸發回調之前被垃圾回收。這意味着如果計時器是全局性的,然後在我到達RunStateMachine時明確處理,它將完美運行......但我不想認爲我解決了它,只是爲了在一個月後間歇性地找到它。

想法?

+0

「掛在信息上」是什麼意思?看起來不像任何可能卡住的聲明。 –

+0

請勿使用標籤進行調試。查找System.Diagnostics.Debug.Print()並收集更多信息。 –

+0

@亨克霍特曼,術語是不正確的,那麼。 「程序停止了,因爲它沒有運行其他任何東西,不是因爲任何東西被阻塞。」我覺得「掛斷」會更簡潔,但我明白它有不同的含義。至於使用Debug。打印而不是標籤:總的來說,我同意,但因爲在此之前我不知道應用程序停止*或*如果我可以訪問停止打印後的內容,我需要在屏幕上更新的內容。不過謝謝你的提示。 –

回答

6

我的理論是,它是在定時器 觸發回調之前收集垃圾。這意味着如果計時器是全球性的,然後 然後明確當我到達RunStateMachine,它將 完美運行......但我不想認爲我解決了它只是爲了找到 這個即將間斷地一個月現在起。

看起來你要確認這是你的問題。 是的,這是問題所在。

計時器存儲在一個永遠不會再使用的局部變量中。這使它符合GC的條件。定時器的GC調整導致定時器被禁止。

我建議您將計時器存儲在表單類的實例字段中,並在回調觸發後將其從計時器中刪除。