2008-11-06 75 views
6

我有一個應用程序具有以下基本架構:如何調試.NET遠程調用?

註冊.NET類型(遠程對象)的遠程訪問(.NET Remoting)的Windows服務(服務)。 RemoteObject創建使用ThreadPool執行IO處理的非ThreadPool線程。由於特定的原因,ThreadPool的大小必須限制在一個限制內。 GUI應用程序使用.NET Remoting訪問RemoteObject。

我注意到,如果ThreadPool的大小太小,在調用RemoteObject時,GUI應用程序將掛起。

我的問題是,我該如何弄清楚爲什麼會掛起,以及爲什麼RemoteObject線程會受到ThreadPool的影響?

這讓我瘋狂;感謝您的幫助!

+0

好吧,你說「RemoteObject創建使用ThreadPool執行IO處理的非ThreadPool線程。」這不是原因(即非ThreadPool線程正在等待ThreadPool插槽打開)嗎? – Alan 2008-11-06 18:30:58

+0

爲什麼會影響RemoteObject所在的線程? GUI甚至無法進入它調用的RemoteObject方法。 – Chris 2008-11-06 18:38:22

+0

如果你可以擺動這個,爲WCF提供遠程控制。 – Will 2008-11-06 19:02:04

回答

4

事實證明,.NET遠程處理基礎結構使用.NET ThreadPool(或共享底層資源),因此如果所有ThreadPool線程都被您的應用程序使用,則遠程處理調用可能會掛起。

2

這可能不是特別有幫助,但我會反正在那裏拋出它。

在調試通過遠程處理的服務和客戶端時,通常我會運行兩個調試器實例:一個用於客戶端,另一個用於服務。爲了清楚起見,我正在運行兩個視覺工作室。對於該服務,您可以使用attach命令,也可以直接更改main和call start(繞過所有服務代碼)。

這裏是我通常通過改變main來啓用調試,您將不得不通過DebugService調用服務,它實際上只是一個調用start的入口點。一旦我有了這個,我只需通過定義SERVICE_DEBUG來啓用服務調試,或者通過添加'!'來更改#if。現在,您基本上已將您的服務轉換爲控制檯應用程序。

#if SERVICE_DEBUG 
      ServiceHost s = new ServiceHost(); 
      s.DebugService(); 
      Thread.Sleep(300000000); 

#else 
      ServiceBase.Run(ServicesToRun); 
#endif 

一旦你有兩種設置和運行,就可以逐步完成客戶端,當遠程電話打到你可以逐步的服務代碼,讓您在同一時間同時調試服務。

出於好奇你是直接從GUI線程調用遠程對象嗎?如果是這樣,GUI線程將阻塞,直到遠程調用完成。這將鎖定整個GUI並使其無響應。這不是解決問題的辦法,但如果是這種情況,並且服務線程沒有返回,它也會導致GUI掛起。

4

我不知道這是否會幫助(我不知道如果這是你的問題或沒有),但如果你要調試服務爲它的運行,你可以在你的代碼拍這樣的:

#if DEBUG 
      if (!System.Diagnostics.Debugger.IsAttached) 
       Debugger.Launch(); 
#endif 

然後您會看到一個對話框,要求您選擇一個調試器。它是一種簡單的方法來附加到服務的運行實例。如果沒有其他的東西,這會讓你在用戶界面掛起時(通過按下調試工具欄上的暫停按鈕)闖入你的服務並檢查你的線程和callstack。

1

幾年前,我設計和實現了一個使用.NET Remoting的關鍵業務系統。我們將客戶端實現爲Windows窗體GUI,作爲Windows服務實現的服務器和SQL Server數據庫。

我設計用於故障排除/調試/開發,所以我的第一個設計標準之一是我可以輕鬆地刪除整個.NET Remoting實現並在我的桌面上運行整個系統。所以,我可以通過將單個布爾配置設置更改爲「false」= off來禁用遠程處理。然後,我可以排除故障,調試,完全開發,而無需.NET Remoting的開銷或干擾。

看來這對你的情況也是有價值的。事實上,我無法想象這種情況不是一個理想的特徵,特別是因爲它很容易實現。

因此,爲了實現它,每個客戶端和服務器代碼都使用配置設置來決定實例化哪個實現類與另一端通信。所有的通信都是通過一個定製的C#接口實現的,每個接口有兩個具體的實現類:一個類使用.NET Remoting實現通信,另一個類將通信實現爲直接進程內直通(直接調用)。

只有一對類(每邊一個)對.NET Remoting有所瞭解,所以隔離是完全的。大多數情況下,所有開發人員都在關閉遠程處理,這更快更簡單。當他們需要的時候,在罕見的情況下,他們會打開它(主要是我,或者當有人連接到測試/生產進行故障排除時)。

順便說一句,我所做的遠程接口死的簡單: 公開回應執行(請求)

除此之外,我還用調試器發射尖上面提到的,我同意,你必須牢記的對GUI線程的影響。