C# .NET远程处理:如何处理断开连接的对象

C# .NET远程处理:如何处理断开连接的对象,c#,asp.net,remoting,C#,Asp.net,Remoting,首先,让我解释一下我的设置。我的服务器被设置为封送单例对象: RemotingServices.Marshal(lsServer, ServerObject.objectUri); 为了实现从服务器到客户端的双向通信,客户端激活一个ServerObject,然后传入自己的ClientObject(也是MarshallByRefObject)。服务器使用ClientObject与客户端进行对话: var lsClient = new ClientObject(); var lsServer

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

 RemotingServices.Marshal(lsServer, ServerObject.objectUri);
为了实现从服务器到客户端的双向通信,客户端激活一个ServerObject,然后传入自己的ClientObject(也是MarshallByRefObject)。服务器使用ClientObject与客户端进行对话:

var lsClient = new ClientObject();

var lsServer = (ServerObject)Activator.GetObject(typeof(ServerObject), url);
lsServer.attach(lsClient);
调用attach方法时,服务器获取ClientObject并将其存储在列表中:

public void attach(ClientObject client) {
    clientList.Add(client);
}
然后,服务器可以调用ClientObject上名为“SendMessage”的方法与列表中的每个客户端通信:

foreach(var c in clientList) {
    c.SendMessage("Hello");
}
在遇到已断开连接的客户机之前,这非常有效。在这种情况下,会抛出一个关于客户端拒绝连接的错误。我可以捕获错误,但问题是我无法从服务器列表中删除对ClientObject的引用。每当客户端断开连接时,以下操作将重新引发“连接被拒绝”异常:

clientList.Remove(badClient);
有几个问题:

1-是否有一种方法可以检测客户端的连接状态而不必捕获错误

2-当我检测到一个已断开连接的客户机时,为什么尝试从服务器列表中删除该对象似乎与客户机“通信”(从而导致再次抛出异常?)

编辑

正如Patrick在下面指出的,从列表中删除会导致列表迭代我的对象并对它们进行比较(调用.Equals)——这就是导致我的ClientObject再次尝试通信并因此引发异常的原因

为了解决这个问题,我将列表改为一个字典,并在连接到服务器时输入了客户端提供的唯一ID。然后我用这个唯一的ID删除了客户端

除了捕捉到错误之外,我从未找到一种直接的方法来确定客户机是否已断开连接。

在#2上不确定。但是,如果您试图从foreach循环内部的
clientList
中删除某个项目,则无法执行此操作。这是一条.NET规则--在枚举可枚举对象时,不能更改其内容


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

谢谢,事实上,在For循环期间,我不会将其从列表中删除。该错误与无法修改集合有关。当我执行clientList.Remove(badClient)时,它会抛出一个“连接被拒绝”异常。。。这看起来很奇怪,但似乎仅仅通过引用“badClient”它就试图使用对象与客户端通信。什么是clientList——一个列表?Remove方法首先执行IndexOf,以查看传入的对象是否确实存在于集合中。在这种情况下,IndexOf可以调用对象的Equals操作符,也可以调用GetHashCode()。这两个调用中的任何一个都会通过线路发送,因此会导致额外的通信异常。是的,这是一个列表,这是有意义的。