У меня есть приложение со следующей базовой архитектурой:
Служба Windows (Служба), которая регистрирует тип .NET (RemoteObject) для удаленного доступа (.NET Remoting). RemoteObject создает потоки, отличные от ThreadPool, которые используют ThreadPool для обработки ввода-вывода. Размер ThreadPool должен быть ограничен до предела по определенной причине. Приложение с графическим интерфейсом пользователя использует .NET Remoting для доступа к RemoteObject.
Я заметил, что если размер ThreadPool слишком мал, приложение с графическим интерфейсом будет зависать при вызове RemoteObject.
У меня вопрос: как понять, почему он зависает и почему ThreadPool влияет на поток RemoteObject?
Это сводит меня с ума; Спасибо за помощь!
Почему это повлияет на поток, в котором находится RemoteObject? Графический интерфейс даже не может войти в вызываемый им метод RemoteObject.
Если вы можете это сделать, откажитесь от удаленного взаимодействия для WCF.
Кристофер, смотри самый нижний абзац моего ответа. Вы вызываете пульт из потока графического интерфейса или обрабатываете его асинхронно?





Это может быть не очень полезно, но я все равно выброшу его туда.
При отладке служб и клиентов, которые общаются через удаленное взаимодействие, я обычно всегда запускаю два экземпляра отладчика: один для клиента и один для службы. Для ясности, я использую две копии Visual Studio. Для службы вы можете использовать команду attach или изменить основной и запустить вызов напрямую (минуя весь служебный код).
Вот как я обычно включаю отладку, изменяя главное, вам нужно и вызов службы DebugService, на самом деле это просто точка входа, которая вызывает start. Как только у меня есть это, я просто включаю отладку службы, определяя SERVICE_DEBUG или меняя #if, добавляя '!'. Теперь вы в основном преобразовали свою службу в консольное приложение.
#if SERVICE_DEBUG
ServiceHost s = new ServiceHost();
s.DebugService();
Thread.Sleep( 300000000 );
#else
ServiceBase.Run( ServicesToRun );
#endif
После того, как вы настроили и запустили, вы можете пройти через клиент, когда вызовы удаленного взаимодействия попадут в службу, вы можете пройти через код службы, что позволит вам отлаживать и то и другое одновременно.
Из любопытства вы вызываете удаленный объект непосредственно из потока графического интерфейса? Если это так, поток графического интерфейса будет заблокирован до завершения вызова удаленного взаимодействия. Это заблокирует весь графический интерфейс и сделает его невосприимчивым. Это не решение проблемы, но если это так и ваш служебный поток не возвращается, это также приведет к зависанию графического интерфейса.
! не очень хорошо, так как он будет переключать его, лучше добавьте к нему префикс 'n'.
Я не уверен, поможет ли это (я не могу сказать, ваша проблема в этом или нет), но если вы хотите отладить свою службу во время ее работы, вы можете вставить это в свой код:
#if DEBUG
if (!System.Diagnostics.Debugger.IsAttached)
Debugger.Launch();
#endif
и вы получите диалоговое окно с просьбой выбрать отладчик. Это простой способ присоединиться к работающему экземпляру службы. По крайней мере, это позволит вам проникнуть в вашу службу, когда пользовательский интерфейс завис (нажав кнопку паузы на панели инструментов отладки), и проверить свои потоки и стек вызовов.
У меня нет проблемы с спрашивающими, но это решение мне очень помогло. :)
Несколько лет назад я разработал и внедрил критически важную бизнес-систему, в которой использовалась .NET Remoting. У нас был клиент, реализованный как графический интерфейс Windows Forms, сервер, реализованный как служба Windows, и база данных SQL Server.
Я проектировал для устранения неполадок / отладки / разработки, поэтому одним из моих первых критериев проектирования было то, что я мог тривиально удалить всю реализацию .NET Remoting и запустить всю систему на моем рабочем столе. Итак, я мог деактивировать удаленное взаимодействие, изменив один логический параметр конфигурации на «false» = off. Тогда я мог полностью устранять неполадки, отлаживать и разрабатывать без дополнительных затрат или вмешательства .NET Remoting.
Похоже, это было бы полезно и для вашей ситуации. На самом деле, я не могу представить себе ситуацию, в которой это нежелательно, тем более что ее легко реализовать.
Таким образом, для его реализации каждый из клиентских и серверных кодов использовал параметр конфигурации, чтобы решить, какой класс реализации создать для связи с другой стороной. Все коммуникации происходили через настраиваемый интерфейс C#, который имел два конкретных класса реализации на каждой стороне: один класс реализовал коммуникацию с использованием .NET Remoting, другой класс реализовал коммуникацию как прямую внутрипроцессную передачу (прямые вызовы).
Только одна пара классов (по одному с каждой стороны) знала что-либо о .NET Remoting, поэтому изоляция была полной. Большую часть времени все разработчики работали с отключенным удаленным взаимодействием, что было быстрее и проще. Когда им было нужно, в редких случаях они включали его (в основном только я или когда кто-то подключался к тестированию / производству для устранения неполадок).
Кстати, я сделал интерфейс удаленного взаимодействия предельно простым: публичный ответ выполнить (запрос)
Помимо этого, я также использовал упомянутый выше совет по запуску отладчика и согласен с тем, что вам нужно помнить о влиянии на потоки графического интерфейса.
Оказывается, инфраструктура удаленного взаимодействия .NET использует .NET ThreadPool (или совместно использует базовый ресурс), поэтому вызовы удаленного взаимодействия могут зависать, если все потоки ThreadPool используются вашим приложением.
Ну, вы говорите: «RemoteObject создает потоки, не относящиеся к ThreadPool, которые используют ThreadPool для обработки ввода-вывода». Разве это не причина (т. Е. Потоки, не относящиеся к ThreadPool, ждут открытия слотов ThreadPool)?