2011-06-09 170 views
0

我有一個計時器事件,每秒觸發。有時當我退出程序(在VS調試器中)時,它告訴我事件線程正試圖訪問不再存在的對象(因爲主線程已結束)。我在退出之前嘗試禁用該事件(UpdateTime.aTimer.Enabled = false;)。這樣可以減少發生此問題的次數,但有時會發生這種情況,因爲事件在我禁用之前會觸發。殺死事件線程

  1. 這是一個嚴重的問題?如果我不處理它,Will會困擾我嗎?
  2. 如果對上述是,我該如何殺死它?

我問第二個問題,因爲我沒有參考事件線程,所以我不知道如何告訴它停止或等待它完成。

編輯:更多的上下文。這是一個Winform。

此外,我沒有明確創建一個線程。這是我的理解,一個線程是自動創建來處理事件。

創建定時器:

public static void Update(){ 

    System.Timers.Timer aTimer = new System.Timers.Timer(1000); 
    aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
    aTimer.Enabled = true; 

} 

事件處理程序:

private static void OnTimedEvent(object source,ElapsedEventArgs e) { 

    Form1obj.updateLabel(String.Format("{0}", DateTime.Now.Second),Label1); 

} 

關閉程序處理程序:

private void Form1_FormClosing(object sender,FormClosingEventArgs e) { 

    aTimer.Enabled = false; 

} 

回答

3

嚴重的問題?可能不會,但我認爲一個問題不需要認真解決。例如,警告在編譯時應被視爲錯誤。另外,如果這是發送給客戶端的應用程序,則在關機時顯示醜陋的錯誤並不是很專業。

如何解決這個問題取決於你如何設置線程(「事件線程」沒有提供關於機制的足夠信息)。一個簡單的方法可能是在應用程序關閉時停止主線程,直到線程全部返回。在此期間,您還必須停止發佈新線程。

另一個可能的解決方案是處理線程的創建方式,以便關閉啓動它們的進程。想到像ThreadPool這樣的概念。確保線程是後臺線程,明確地說,可以在某些情況下提供幫助。

簡短的回答是沒有人會給你一個堅定的「這將解決你的問題」的答案,沒有你在你的代碼中做什麼的背景。

增加:

有一對夫婦的「快,降濁」的方式來處理這個問題。沒有足夠的時間進行全面的分析,所以看看它們是否有效。

  1. 通過等待
  2. 添加計數器,等到加下來就改正錯誤

我會考慮的是增加一個安全網,而不是當處於關機狀態更新標籤的第一件事。這與其他任何事情無關,因爲這是你的錯誤發生的地方。我不認爲「主要思路是不存在」是問題的核心,而這條線:

Form1obj.updateLabel(String.Format("{0}", DateTime.Now.Second),Label1); 

你怎麼能更新的東西,不再存在?是的,這是在主線程上,所以在技術上...

一個簡單的等待會是這樣的:

private void Form1_FormClosing(object sender,FormClosingEventArgs e) 
{ 
    aTimer.Enabled = false; 
    Thread.Sleep(5000); 
} 

隱藏形式也未嘗不可,因此用戶並不認爲這是?

如果您想使用更多「類似COM的方法」,您可以添加一個計數器。 Update()(當事件被觸發時)時遞增,OnTimedEvent()時遞減。確保在更改計數器時鎖定計數器,以免兩個線程在同一毫秒內更改計數器。然後您可以等到計數器爲0以完成關閉或應用程序卸載。

再次,這些是快速,簡單和骯髒的方法,但它們可以幫助您避免錯誤。我相信有更多時間的人可以想出更優雅的解決方案。

0

這個問題很難給出一個普遍的問題,如果問題嚴重的話,這取決於計時器在做什麼。它是什麼樣的計時器?一個系統。對一個或一個UI定時器進行線程化?

如果可能的話,嘗試並重構代碼,以便您可以告訴定時器停止觸發,如果僅僅是爲了不讓用戶誤解錯誤信息。它可以像使用共享變量或(最好)一樣簡單CancellationToken

1

您可以關閉該窗口as suggested in MSDN - 當你設置定時關機處理過程中被禁用,設置你的Elapsed事件處理程序可以檢查標誌知道不需要更多的工作。

經過的事件 處置或停止方法後,可能會出現被稱爲 或Enabled屬性後一直 設置爲false,因爲信號 擡高經過的事件總是 排隊等待執行上線程池 線程。解決此種族的一種方法 條件 是設置一個標誌,告知事件 處理程序爲Elapsed事件爲 忽略後續事件。