.NET Remoting:如何处理断开连接的对象

时间:2010-10-26 20:21:21

标签: c# asp.net remoting

首先,让我解释一下我的设置。我的服务器设置为Marshaled单例对象:

 RemotingServices.Marshal(lsServer, ServerObject.objectUri);

为了从服务器到客户端进行双向通信,客户端激活ServerObject,然后传入自己的ClientObject(也是MarshalByRefObject),服务器使用ClientObject与客户端进行对话: / p>

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删除客户端。

我从未找到确定客户端是否已断开连接而不是捕获错误的直接方法。

1 个答案:

答案 0 :(得分:0)

在#2上不确定。但是,如果您尝试从foreach循环内部移除clientList中的项目,则不能。这是一个.NET规则 - 在枚举时不会更改可枚举对象的内容。

相反,如果您在foreach循环中捕获错误,请将其存储在另一个列表中(“已断开连接”列表)。在foreach之后,从clientList删除所有已断开连接的项目。