1. используя метод Layer.GetIncidentElements, но возникает сообщение о нехватке памяти 2. в цикле используя метод NetworkObjects.GetIncidentKeys, через какое-то время здесь возникает System.OutOfMemoryException, после возникновения ошибки, при закрытии соединения, соединение закрывается некорректно, из-за чего наступает блокировка по кол-ву подключений на IP-адрес. Попытался еще добавить задержку между запросами (500 мс), но возникло другое исключение: HRESULT: 0x80010105 (RPC_E_SERVERFAULT)).
Как обойти проблему и получить всю структуру теплосети от Источника?
Язык программирования: C# Версия ZuluServer: 8.0.0.7290u
1. используя метод Layer.GetIncidentElements , но возникает сообщение о нехватке памяти 2. в цикле используя метод NetworkObjects.GetIncidentKeys , через какое-то время здесь возникает System.OutOfMemoryException, после возникновения ошибки, при закрытии соединения, соединение закрывается некорректно, из-за чего наступает блокировка по кол-ву подключений на IP-адрес.
Как обойти проблему и получить всю структуру теплосети от Источника?
Язык программирования: C# Версия ZuluServer: 8.0.0.7290u
Пришлите фрагмент кода, где метод используется. А вообще, сеть получают через Layer.NetWorkObjects
Быкиев Андрей написал: Вот мой рекурсивный метод (с логикой обхода циклов):
Код
private static void GetChildren(int key, int prevKey, Layer layer)
{
int[] incidentKeys = layer.NetworkObjects[eNetworkObjectFilter.eNetworkAll].GetIncidentKeys(key, eIncidentRelationship.eIncidentAll).SaveToArray();
for (int i = 0; i < incidentKeys.Length; i++)
{
GetChildren(incidentKeys[i], key, layer);
}
}
[CODE][/CODE]
Понятно. Вы рекурсивно по числу элементов сети создаете объект layer.NetworkObjects, который засасывает с сервера столько же раз всю сеть. Это законно приводит к нехватке памяти. Если сеть большая, то быстро приведет.
GetIncidentKeys тоже рекурсивно создает коллекции, которые не высвобождаются и растут как снежный ком.
При определенной глубине сети и стека не хватит. не знаю возможности конкретно C##
Рекурсия вещь красивая, но опасная. Уходить вглубь нужно, не оставляя на каждом уровне объекты, занимающие память, размером с объем данных всего слоя или его части.
Алексей, спасибо, свою проблему понял, сейчас изменю логику. Остается пока вопрос - почему некорректно закрывается подключение при OutOfMemoryException именно при вызове этого метода через Layer.NetWorkObjects, метод Disconnect при этом не выдает никаких ошибок?
Быкиев Андрей написал: Алексей, спасибо, свою проблему понял, сейчас изменю логику. Остается пока вопрос - почему некорректно закрывается подключение при OutOfMemoryException именно при вызове этого метода через Layer.NetWorkObjects , метод Disconnect при этом не выдает никаких ошибок?
Да, еще. Объект NetworkObjects нужно получить с сервера один раз. Это и есть вся сеть. И дальше с ним работать. Иначе есть риск, что при многопользовательском редактировании будете при разных обращениях к серверу за сетью, получать разные состояния сети
Спасибо, убрал из рекурсии запрос NetworkObjects и проблема решилась. Но все равно, вопрос с закрытием соединения при ошибке в Zulu остался открытым. Я перехватываю исключение в try/catch и в блоке finally всегда закрываю соединение.
Быкиев Андрей написал: Спасибо, убрал из рекурсии запрос NetworkObjects и проблема решилась. Но все равно, вопрос с закрытием соединения при ошибке в Zulu остался открытым. Я перехватываю исключение в try/catch и в блоке finally всегда закрываю соединение.
Тут нужно конкретно смотреть конкретный модуль. Соединение при аварийном завершении непредсказуемое дело. Если деструктор слоя, например, не вызвался, то и отсоединения не будет. Для этого штатно должны удалиться все объекты, связанные со слоем. И т.д. По идее сервер по таймеру должен, спустя время, соединение закрыть, если нет жизнедеятельности. Но тоже не всегда. Чтобы исследовать, нужно воспроизвести ситуацию. Пришлите, если можно, модуль с ошибкой. Попробую воспроизвести