簡體   English   中英

.NET Remoting:如何處理斷開連接的對象

[英].NET Remoting: How to handle disconnected objects

首先,讓我解釋一下我的設置。 我的服務器被設置為Marshaled單例對象:

 RemotingServices.Marshal(lsServer, ServerObject.objectUri);

為了從服務器到客戶端進行雙向通信,客戶端激活ServerObject,然后傳入自己的ClientObject(也是MarshalByRefObject),服務器使用ClientObject與客戶端進行對話:

var lsClient = new ClientObject();

var lsServer = (ServerObject)Activator.GetObject(typeof(ServerObject), url);
lsServer.attach(lsClient);

調用attach方法時,服務器獲取ClientObject並將其存儲在List中:

public void attach(ClientObject client) {
    clientList.Add(client);
}

然后,服務器可以調用名為“SendMessage”的ClientObject上的方法,以便與其列表中的每個客戶端進行通信:

foreach(var c in clientList) {
    c.SendMessage("Hello");
}

這種方法很有效,直到遇到斷開連接的客戶端。 在這種情況下,會拒絕客戶端拒絕連接的錯誤。 我可以捕獲錯誤,但問題是我無法從服務器的List中刪除對ClientObject的引用。 以下在客戶端斷開連接時重新拋出“連接被拒絕”異常:

clientList.Remove(badClient);

所以有幾個問題:

1-有沒有辦法檢測客戶端的連接狀態而不必捕獲錯誤?

2-當我檢測到已斷開連接的客戶端時,為什么從服務器列表中刪除對象的嘗試似乎與客戶端“通信”(從而導致再次拋出異常?)

編輯

正如Patrick在下面指出的那樣,從列表中刪除會導致List迭代我的對象並對它們進行比較(調用.Equals) - 這就是導致我的ClientObject再次嘗試通信並因此拋出異常的原因。

為了解決這個問題,我改為將List更改為一個字典,該字典是在我的客戶端連接到服務器時提供的唯一ID。 然后我使用該唯一ID刪除客戶端。

我從來沒有找到一種直接的方法來確定客戶端是否已斷開連接而不是捕獲錯誤。

在#2上不確定。 但是,如果您嘗試從foreach循環內部從clientList刪除項目,則不能。 這是一個.NET規則 - 在枚舉時不會更改可枚舉對象的內容。

相反,如果您在foreach循環中捕獲錯誤,請將其存儲在另一個列表中(“已斷開連接”列表)。 在foreach之后,從clientList刪除所有斷開連接的項目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM