Фон:WCF NetTCP с фоновой резьбой
У меня есть система, которая содержит службы WCF внутри службы Windows с привязкой NetTCP. Чтобы добавить новую службу в коллекцию, вы просто добавляете стандартные записи конфигурации WCF внутри < system.serviceModel -> services />, а затем добавляете строку внутри настраиваемого раздела конфигурации, в котором говорится, что инфраструктура хостинга необходима для инициализации службы. Каждая служба инициализируется собственным фоновым потоком и экземпляром AppDomain, чтобы все было изолировано.
Вот пример того, как услуги инициализируются:
Host
- ServerManager
- ServiceManager
- BaseServerHost
Экземпляр ServerManager имеет коллекцию ServiceManagers, что каждый коррелируют к одному экземпляру службы, которая где стандарт 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
Когда я ловлю исключение на фоне потока в бизнес-слоя I пузыря его к экземпляру Endpoint (который наследуется от BaseServerHost), который затем пытается стрелять UnhandledException BaseServerHost в событие для этой конкретной службы (к которой был прикреплен владелец ServiceManager, который его создал). К сожалению, обработчик событий больше не существует, поэтому он ничего не делает. Я пробовал много вещей, чтобы заставить это работать, и до сих пор все мои усилия были напрасны.
Если вы посмотрите на полную модель (показано ниже), мне нужно, чтобы бизнес-уровень знал о его родительской конечной точке (это работает), и конечная точка должна знать о запущенном экземпляре BaseServerHost, который должен знать о ServiceManager, который размещает его так, что ошибки могут быть взорваны до этого для использования в наших стандартных процедурах регистрации.
Host
- ServerManager
- ServiceManager <=====================
- BaseServerHost ||
- Endpoint (svc) ||
- Business Layer <======
- Data Layer
Я пробовал статические классы не повезло, и даже дошел до того, что делает ServerManager статические и expoting его ранее внутреннюю коллекцию ServiceManagers (так что они могут быть отключение), но коллекция всегда пустой или нулевой слишком ,
Мысли о выполнении этой работы?
EDIT: После копания немного дальше я нашел пример того, как именно я это вижу. На стандартном веб-сайте ASP.NET на любой странице/обработчике и т. Д. Вы можете использовать свойство HttpContext.Current для доступа к текущему контексту для этого запроса. Именно так я хотел бы, чтобы это работало с «ServiceManager.Current», возвращая владелец ServiceManager для этой службы. Может быть, это помогает?
Это определенно выглядело многообещающим с высокого уровня, и я надеюсь, что это именно то, как я его реализовал, что заставляет его не работать. Сразу после инициализации службы (BaseServerHost) я делаю это: CallContext.SetData («ApplicationName», ApplicationName); CallContext.SetData (ApplicationName + "ServiceManager", это); Когда я использую непосредственное окно справа, я могу увидеть экземпляр ServiceManager. Однако, когда я получаю исключение, CallContext.GetData («ApplicationName») имеет значение NULL. Надеюсь, вы можете найти некоторые ссылки, как это сделать, поскольку я должен что-то делать неправильно. – RubyHaus
@digitall - я добавил дополнительную информацию и некоторые ссылки. Мне непонятно, что идея, о которой я думал, обязательно применима к тому, как работает ваша система. Надеюсь, в моем ответе будет достаточно информации, что вы сможете сказать, применимо ли то, о чем я говорю, или нет. – wageoghe
Я не забыл об этом - меня вызвали в командировку, и я не смогу снова взглянуть на неделю или около того. В то время я буду копать немного дальше. – RubyHaus