Справочная информация:
У меня есть система, в которой размещаются службы WCF внутри службы Windows с привязкой NetTCP.Чтобы добавить новый сервис в коллекцию, вы просто добавляете стандартные записи конфигурации WCF внутриservices />, а затем добавьте строку внутри пользовательского раздела конфигурации, которая сообщает платформе хостинга, что ей нужно для инициализации службы.Каждая служба инициализируется с собственным фоновым потоком и экземпляром AppDomain, чтобы держать все изолированными.
Вот пример инициализации служб:
Host
- ServerManager
- ServiceManager
- BaseServerHost
Экземпляр ServerManager имеет коллекциюМенеджеры ServiceManager, каждый из которых соответствует одному экземпляру службы, в котором находится стандартная реализация WCF (ServiceHost.Open/Close и т. Д.).Экземпляр ServiceManager создает экземпляр (на основе конфигурации - он имеет стандартное определение сборки / типа) экземпляр службы с использованием базового класса BaseServerHost (аннотация).Каждый сервис должен наследовать от этого, чтобы инфраструктура могла его использовать. В рамках процесса инициализации BaseServerHost предоставляет пару событий, в частности событие UnhandledException, к которому присоединяется владелец ServiceManager. (Эта часть является критической в отношении вопроса, приведенного ниже.)
Весь этот процесс работает исключительно хорошо для нас (один экземпляр запускает 63 службы), так как я могу привлечь кого-то, кто ничего не знает о WCF, и они могут создавать службы очень быстро.
Вопрос:
Проблема, с которой я столкнулся, связана с фоновым потоком.Большинство открытых методов на наших конечных точках выполняют значительную активность после стандартного вызова метода вставки / обновления / удаления, такого как отправка сообщений в другие системы.Чтобы сохранить производительность (интерфейс является веб-интерфейсом), мы позволяем начальному методу вставки / обновления / удаления делать свое дело, а затем запускаем фоновый поток для обработки всего, что конечному пользователю не нужно ждатьзавершить.Эта опция прекрасно работает до тех пор, пока что-то в этом фоновом потоке не будет обработано и отключит всю службу Windows, что, как я понимаю, разработано (и я в порядке).
На основании всех моих исследований, которые я обнаружилчто нет никакого способа реализовать глобальную попытку / поймать (за исключением использования взломанного конфига, включающего 1.1 обработку фоновых сбоев), поэтому моей команде придется вернуться и получить их в соответствующих местах.Кроме того, то, что я обнаружил, находится на стороне конечной точки хостинга WCF, похоже, в своем собственном потоке при каждом вызове, и заставить этот поток общаться с «родителем» было кошмаром.С точки зрения службы, вот макет:
Endpoint (svc - inherits from BaseServerHost, mentioned above)
- Business Layer
- Data Layer
Когда я ловлю исключение в фоновом потоке на бизнес-уровне, я раздуваю его с экземпляром Endpoint (который наследуется от BaseServerHost), который затем пытается запуститьСобытие UnhandledException в BaseServerHost для этой конкретной службы (которая была присоединена владельцем ServiceManager, который его создал).К сожалению, обработчик событий больше не существует, поэтому он вообще ничего не делает.Я пробовал множество вещей, чтобы заставить это работать, и до сих пор все мои усилия были напрасны.
При рассмотрении полной модели (показанной ниже) мне нужно, чтобы бизнес-уровень знал о ееродительская конечная точка (это работает), и конечная точка должна знать о работающем экземпляре BaseServerHost, который должен знать о ServiceManager, на котором он размещается, чтобы ошибки можно было связать с этим для использования в наших стандартных процедурах регистрации.
Host
- ServerManager
- ServiceManager <=====================
- BaseServerHost ||
- Endpoint (svc) ||
- Business Layer <======
- Data Layer
Я безуспешно пробовал статические классы и даже зашел до того, что сделал ServerManager статичным и экспортировал свою ранее внутреннюю коллекцию ServiceManager (чтобы их можно было отключить), но эта коллекция также всегда пуста или равна нулю.
Мысли о том, чтобы сделать эту работу?
РЕДАКТИРОВАТЬ: После копания немного дальше, я нашел пример того, как именно я представляю эту работу. На стандартном веб-сайте ASP.NET на любой странице / обработчике и т. Д. Вы можете использовать свойство HttpContext.Current для доступа к текущему контексту для этого запроса. Именно так я и хотел бы, чтобы это работало с ServiceManager.Current, возвращающим владеющий ServiceManager для этой службы. Возможно, это помогает?