2011-04-14 62 views
2

我在觀察我的代碼中的一些奇怪行爲,並試圖追蹤源代碼。我有兩個單線程的.net應用程序在同一臺機器上運行並向對方發送WCF消息。它們非常簡單,有阻塞寫入,然後是阻塞讀取。我已經注意到,在我的日誌中的阻塞呼叫中,99.99%的時間在〜10 ms內讀取/寫入。但在極少數情況下,可能需要500-2000毫秒。我想明白爲什麼會這樣。我有幾個奇怪的怪癖我的應用程序,我跟蹤下來,可能是罪魁禍首,但我想知道,這是進入領地裏有一些關於我不明白的框架。.net框架在阻塞呼叫期間做了什麼?

所以我的問題是這樣的,當有一個像一個阻塞調用,並在.NET應用程序開始運行後臺進程(如垃圾回收),而執行的主線程被阻塞?

謝謝你的時間。因此,如果您使用的是阻塞調用與否並不重要

+0

垃圾收集可能是罪魁禍首。任何數量的事情都可能導致延誤。例如,操作系統可能會將一個或兩個線程交換出內存來執行其他操作。或者更高優先級的線程阻止一個或兩個線程運行。很難說。你能發佈一些代碼,以便我們更好地瞭解你遇到問題的位置嗎? – 2011-04-14 21:35:05

回答

3

垃圾收集器都有自己的專用資源。

阻塞調用基本上意味着運行UI線程在長時間運行的任務。根據應用程序的類型(WPF,Windows,Console),UI線程的定義不同,但在UI線程上運行任務時,UI線程的所有消息都會排隊。

你看到可能的影響因例如磁盤網絡瓶頸造成的長時間運行的任務延遲其他一些問題。使用perfmon並將您的延遲時間與perfmon日誌相匹配可能很有用。

+0

感謝您的測試建議。我會嘗試一下,看看我可以消耗多少。我意識到性能是一個複雜的問題,所以我試圖排除.net性能下降,我可能不知道。謝謝你解決GC和perfmon的想法。 – Dio 2011-04-14 21:45:43

+0

這看起來像是一個古怪的例子,例如睡眠後或類似的硬盤驅動器主軸醒來。 – Aliostad 2011-04-14 21:46:44

2

所以我的問題是這樣的,當有 像一個阻塞調用,做了 .NET應用程序開始運行一個 後臺進程(如垃圾 收集),而 執行的主線程被阻塞?

CLR在阻塞調用期間所做的是完全非確定性的,而不是您可以依賴的東西。您觀察到的差異可能是由於許多因素無法控制,例如網絡延遲。

4

你需要考慮到一個事實,即有許多您的系統上運行的其它應用。通常事情可能會平穩運行,但每隔幾次,您可能會有幾個應用程序爭奪處理器時間,這會導致您看到延遲。您看到.01%的時間的奇怪的延遲可能與.NET毫無關係,並且與操作系統在特定時間點發生的更多有關。

我不認爲這個問題是與垃圾收集。你的應用聽起來相當簡單和緊密,無論收集什麼垃圾可能都很小。你正在運行一臺開發機器,如果你像大多數開發人員一樣,你將擁有各種各樣的服務器,IDE,文本編輯器和幾十個web瀏覽器選項卡。試試這個:打開較重的應用程序,直到您的物理內存使用率超過75%或更高。 (即使這樣做的Alt + Tab應用程序會顯得之間/是緩慢的。)我猜你會看到更大的延遲,更多的時候,因爲會有更多的頁面錯誤,因此有更多的點擊到硬盤驅動器(主要瓶頸)放緩貫穿整個過程。

+0

好主意,謝謝,我會給它一個鏡頭。我意識到這是一個複雜的問題,有很多的罪魁禍首,我只是想排除我不知道的可能的.net。感謝測試的想法。 – Dio 2011-04-14 21:44:27

0

首先,如果您不使用svctraceutil請務必使用它,因爲它會給你一個信息負載。 WCF的功能取決於您使用服務/客戶端設置的數百個配置選項。假設您在長時間的異常值調用期間使用一些基於tcp的綁定,它將重新建立會話或重新傳輸失敗的數據包。使用框架的好處和壞處是,只要滿足您的需求,您無需擔心具體情況。如果您需要細粒度控制,您可以始終實施自定義綁定或使用原始TCP/IP通信。