2012-12-05 29 views
1

我有一個事件是從第三方庫引發的,後者在後臺線程上執行。該事件基本上通知監聽器在系統中正在監視的狀態更新。如果InvokeRequired爲true,則處理程序在UI線程上自行調用,並且在任一情況下繼續將狀態更改的條目追加到文本框中的文本中,並在托盤中彈出通知。事件處理程序很快出現很多次似乎「短路」

現在,問題在於這些狀態更新可能會非常迅速;被監控的系統可以在幾毫秒內從其「空閒」狀態通過幾箇中間體轉變爲「就緒」狀態。我需要知道系統已經過渡到所有這些中間狀態;但是,並非所有的狀態變化都正在進入日誌。設置一個斷點並單步執行處理程序會顯示最奇怪的行爲;處理程序將逐步完成前幾行代碼,然後跳回到方法的入口。就好像事件或Windows消息泵正在中止方法調用一樣,因爲調用同一方法的另一個調用是傳入的。將方法主體放在鎖定塊中並不能解決問題。

我以前在其他沒有使用這個第三方庫的項目中見過這個。那時我並不擔心,因爲快速事件只是觸發窗口重繪。如果它們都發生了,那麼很好,但如果發生短路,管道中還會有另一個通過。然而,這是一項更重要的應用程序任務,每次事件發生時都必須發生,以便順利進行(不必像州政府實際發生的變化一樣快;絕對不會這樣做)。

這種短路行爲的原因是什麼?如何阻止它?

+0

什麼是日誌記錄機制?也許事件B和C的日誌條目失敗,因爲關鍵資源已被鎖定,因爲它仍在記錄事件A? – Beska

+0

「日誌」非常簡單;它附加到狀態窗口中的文本框的文本,並且如果它是最終用戶感興趣的事件,則彈出通知。非常簡單,但它們需要在UI線程中運行。 – KeithS

回答

0

而不是在線程中同步執行所有的工作,事件處理程序在其中觸發可能有利於在另一個線程中執行該工作。

只是將您在當前事件處理程序中執行的所有操作都包裝在Task.Factory.StartNew中,或者使用BeginInvoke編組到UI線程而不是Invoke

我無法確定,因爲我對該庫沒有任何瞭解,但可能是它無法觸發更多事件,直到它完成前一事件的所有事件處理程序。

你可能需要做的另一個選擇,要麼解決這個問題,要麼防止你的用戶界面在你這麼多的更新中生氣,就是把狀態變化當作進來,然後把它們轉儲到收集,然後定期檢查收集並處理批次中的所有更改。這對於第三方對象的事件處理程序來說會更簡單,因爲它只需將項目添加到集合中,並且在UI上也更容易,因爲它不需要在監視器甚至可以連續多次更新呈現更改。

1

你看到的是最有可能從後臺線程對事件處理程序的新調用,而您首次啓動的調用仍在運行。

+0

如果是這種情況,我會看到光標向前和向後跳轉,或者保持在同一位置,因爲各種線程都在處理程序中咀嚼。我還會在處理程序中看到多個線程。這些似乎都不是這種情況。 – KeithS

+0

@KeithS「處理程序將逐步完成前幾行代碼,然後跳回到方法條目」 - >這是您從後臺線程重新輸入事件處理程序時的樣子。 –

+0

...但是在線程窗口中沒有多個線程被列爲該處理程序中。 – KeithS