2012-04-08 63 views
1

我在這裏的第一篇文章,但這個網站已經回答了我以前有過的許多問題。希望我可以提供足夠的細節來解釋我所面臨的問題,因爲我不完全理解.NET如何處理我創建的線程!System.Threading.Timer導致其他計時器落後

好吧,所以基本上,我有一個線程設置爲每1000ms運行一次從視頻編碼器獲取幀計數器並計算FPS。儘管我意識到它不準確(通常在事件之間超過1000毫秒),但對於現在的System.Threading.Timer來說,精度足夠了。我還有另一個Threading.Timer正在運行並從網絡讀取串行設備。問題是,如果網絡設備變得不可用,並且該定時器上的套接字超時,則FPS定時器將完全不同步!所以他們以前每1015ms執行一次(測量),但是當我啓動另一個Thread.Timer嘗試進行套接字連接並且失敗時,它會導致FPS計數器定時器完全關閉(最高7000ms!)。我不太清楚爲什麼會這樣,而且真的需要FPS計數器幾乎無論如何運行一次。的代碼

位 - >

FPS計數器

private void getFPS(Object stateInfo)//Run once per second 
{ 
    int frames = AxisMediaControl.getFrames; //Axis Encoder media control 
    int fps = frames - prevValue; 
    prevValue = frames; 
    setFPSBar(fps, fps_color); //Delegate to update progress bar for FPS 
} 

電池電量定時器

while (isRunning) 
{ 
    if (!comm.Connected) //comm is standard socket client 
     comm.Connect(this.ip_address, this.port); //Timeout here  causes  other timer threads to go out of sync 

if (comm.Connected) 
{ 
    decimal reading = comm.getBatt_Level(); 
    //Calculate Readings and update GUI 
    Console.Out.WriteLine("Reading = " + (int)prog); 
break;//Debug 

     } 

這是用來連接到插座當前的代碼 - >

public Socket mSocket { get; set; } 
public bool Connect(IPAddress ip_address, UInt16 port) 
{ 
    try 
    { 
     mSocket.Connect(ip_address, port); 
    } 
    catch(Exception ex) 
    { 

    } 
    return mSocket.Connected; 
} 

Hope完全不太含糊!

+0

爲什麼隱藏異常是一個好主意? – 2012-04-08 21:37:00

+0

該軟件將用於會出現很多超時的環境中,並且我認爲每5秒鐘不會顯示一條消息會很有用。我在調試時發現異常,但我期望連接失敗,因爲網絡是無線網絡,並且在操作期間預計會出現退出。你會建議什麼? – jackocurly0074 2012-04-08 21:40:08

+2

我建議捕捉'TimeoutException'或任何你關心的特定異常,並允許其他人傳播。這樣,你會了解其他例外情況。 – 2012-04-08 23:56:09

回答

1

雖然我不知道爲什麼你的FPS定時器不是爲7s調用的,但我可以建議一種解決方法:從上一次通過記住Environment.TickCount值更新FPS值開始測量TimeSpan。然後,將FPS值計算爲(delta_frames/delta_t)。

+0

感謝您的回覆。我認爲這很奇怪,不確定它是否與線程池有關。當測試完整的應用程序時,我有大約5個線程計算每秒幀數和4個電池讀數。此外,有時該軟件似乎在任務管理器中使用多達90個線程,這似乎高得多......!解決方法絕對是一種選擇,但我希望如果可能的話,我可以找到問題的根源! – jackocurly0074 2012-04-08 21:48:54

+2

90個線程太多了。您可能會在此處遇到一些線程池限制,導致定時器ping不被執行。我建議你看看調試器中的線程窗口,看看爲什麼有這麼多的線程。注意,Threading.Timer不會阻塞一個線程,所以這可能不是原因。 – usr 2012-04-08 21:51:14

+0

只是想知道,在看它運行時,看起來很多線程是爲套接字客戶端創建的,因此必須查看它。它也似乎是使用線程來更新FPS計數器的接口(我使用委託),這是更新接口的不好方法嗎?由於每個計時器通過委託進行更新,這似乎是在運行時添加額外的線程。所以當觀看4個視頻流時,這個問題就被放大了! – jackocurly0074 2012-04-08 22:22:21

1

感謝您的評論,我通過以下操作修復了這一問題。

改爲使用System.Timers.Timer,並將自動重置設置爲false。每當其中一個定時器完成時,我再次啓動它,這意味着每個電池設備只有一個定時器。初始解決方案的問題在於網絡超時導致線程保持活動狀態的時間長於定時器間隔。因此,爲了確保定時器間隔得到滿足,一個新線程的產生更頻繁。

在運行期間,這意味着每個電池計時器約有5-7個線程(其中6個超時,1個即將開始)。更改爲新的計時器意味着現在只有一個線程,因爲它應該是。

我還在代碼中添加了基於所需時間計算FPS的方法(使用Stopwatch功能獲得更高精度(謝謝USR))。謝謝您的幫助。我必須確保不要讓例外空白。