2008年5月11日 星期日

ContextSwitchDeadlock

寫程式居然能寫出Deadlock(死結),非常不容易吧!

CLR 在過去 60 秒一直無法從 COM 內容 0x1a04a8 轉換為 COM 內容 0x1a0618。擁有該目的內容/Apartment 的執行緒,很可能正在進行非提取等候或正在處理非常長的執行作業,而未提取 Windows 訊息。這種情況通常會對效能產生負面影響,甚至可能導致應用程式停止回應,或導致記憶體使用量持續隨時間而累積。若要避免這個問題,所有單一執行緒的 Apartment (STA) 執行緒都應該使用提取等候基本方法 (例如 CoWaitForMultipleHandles),並且在長時間的執行作業中定期提取訊息。

在嘗試轉換 COM 內容期間偵測到死結 (Deadlock) 時,ContextSwitchDeadlock Managed 偵錯助理 (MDA) 就會啟動。

症狀:最常見的症狀,就是從 Managed 程式碼到 Unmanaged 程式碼的呼叫沒有傳回。另一種症狀則是記憶體使用量隨著時間逐漸增加。

原因:最可能的原因,就是單一執行緒 Apartment (STA) 執行緒沒有提取訊息。STA 執行緒在等候時未提取訊息,或者在執行漫長作業時不允許提取訊息佇列。當完成項執行緒嘗試對 Unmanaged 元件呼叫 release,而該元件卻沒有傳回時,就會造成記憶體使用量隨著時間逐漸增加。如此,完成項便無法回收其他的物件。

解決方式:遵循有關 STA 訊息提取的 COM 規則。

對執行階段的影響:這個 MDA 對 CLR 無效。它只會報告有關 COM 內容的資料。

輸出:描述目前內容和目標 (Target) 內容的訊息。

ContextSwitchDeadlock