2010-10-26 1 views
3

Во-первых, позвольте мне немного рассказать о моей настройке. Мой сервер настроен как выстраивали единственный объект:.NET Remoting: Как обрабатывать отключенные объекты

RemotingServices.Marshal(lsServer, ServerObject.objectUri); 

Для того, чтобы иметь двустороннюю связь с сервера к клиенту, клиент активирует ServerObject, затем проходит в своем собственном ClientObject (который также является MarshalByRefObject) сервер использует ClientObject говорить клиенту:

var lsClient = new ClientObject(); 

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

Когда присоединять метод вызывается, сервер принимает 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- Когда я обнаружить клиента, который отсоединен, почему попытка удалить объект из списка сервера появится «общаться» с клиентом (тем самым вызывая исключение бросить снова?)

EDIT

Как Патрик указал ниже, делая Удалить из списка вызывает список, чтобы перебирать свои объекты и сделать сравнение на них (вызов .equals) - это то, что вызвало мое ClientObject пытаться снова общаться и, таким образом, исключение.

Чтобы решить эту проблему, я вместо этого изменил список на словарь, на который был установлен уникальный идентификатор, предоставленный моим Клиентом во время присоединения к серверу. Затем я использовал этот уникальный идентификатор, чтобы удалить клиента.

Я никогда не нашел прямого способа определить, был ли клиент отключен, кроме обнаружения ошибки.

ответ

0

Не уверен на # 2. Однако, если вы пытаетесь удалить элемент из clientList из цикла foreach, вы не можете. Это правило .NET - без изменения содержимого перечислимого объекта во время его перечисления.

Вместо этого, если вы поймаете ошибку внутри цикла foreach, сохраните ее в другом списке («отключенный» список). После использования foreach удалите все отключенные элементы из clientList.

+0

Спасибо, на самом деле я не удаляю его из списка во время цикла For. Эта ошибка является чем-то чем-то невозможным для изменения коллекции. Когда я выполняю clientList.Remove (badClient), он бросает исключение «Отказано в подключении» ...что кажется странным, но, похоже, просто ссылаясь на «badClient», он пытается использовать объект для связи с клиентом. – bugfixr

+0

Что такое clientList - список ? Сначала метод Remove делает IndexOf, чтобы увидеть, действительно ли объект, который вы передали, в коллекции. Под обложками IndexOf может вызывать либо оператор Equals вашего объекта, либо, возможно, GetHashCode(). Любой из этих вызовов будет отправлен по кабелю - и, таким образом, приведет к дополнительному исключению связи. – PatrickSteele

+0

Да, это список - это имеет смысл тогда. – bugfixr