Я занимаюсь разработкой службы Windows на C #.
Набор путей к файлам конфигурации предоставляется этой службе при запуске.Для каждого из этих файлов служба раскручивает AppDomain
, используя файл в качестве ConfigurationFile
, а папку этого файла - ApplicationBase
.Каждая папка будет иметь папку «bin», установленную как PrivateBinPath
.
Папка «bin» в этих папках содержит небольшую сборку, которая является общей для службы, эта сборка содержит интерфейс IServiceHost
.Также известно имя типа и имя сборки класса, который реализует интерфейс IServiceHost
.
Весь метод CreateServiceHost
выглядит следующим образом: -
public static IServiceHost CreateServiceHost(string configPath, string entryAssembly, string entryType)
{
IServiceHost host;
AppDomainSetup setupInfo = new AppDomainSetup();
setupInfo.ApplicationBase = Path.GetDirectoryName(configPath);
setupInfo.PrivateBinPath = Path.Combine(setupInfo.ApplicationBase, "bin");
setupInfo.ShadowCopyFiles = "true";
setupInfo.ConfigurationFile = configPath;
AppDomain appDomain = AppDomain.CreateDomain("Service for: " + setupInfo.ApplicationBase, AppDomain.CurrentDomain.Evidence, setupInfo);
object objHost = appDomain.CreateInstanceFromAndUnwrap(Path.Combine(setupInfo.PrivateBinPath, entryAssembly), entryType);
host = (IServiceHost)objHost;
return host;
}
IServiceHost
Интерфейс невероятно сложный: -
public interface IServiceHost
{
void Start();
void Stop();
}
Служба OnStart содержит что-то вроде этого: -
private List<IServiceHost> serviceHosts = new List<IServiceHost>();
protected override void OnStart(string[] args)
{
foreach (string configPaths in GetConfigPaths())
{
IServiceHost host = ServiceHostLoader.CreateServiceHost(configPath);
serviceHosts.Add(host);
host.Start();
}
}
OnStop
одинаково прост (на данный момент для простотыIServiceHost.Stop
блокируют вызовы).
protected override void OnStop()
{
foreach (IServiceHost host in serviceHosts)
{
host.Stop();
}
}
Все это достаточно просто и отлично работает при тестировании на компьютерах разработчиков.Однако в QA я получаю исключения, когда он остановлен.Когда в процессе разработки мы раскручиваем вещи только на короткий период, кажется, что все работает нормально.Однако в QA сервис останавливается только каждые 24 часа.В этом случае он постоянно не может правильно завершиться.
Вот пример того, что заканчивается в журнале событий: -
Тип события: ошибка Источник события: Категория событий Workspace Services Категория события: Нет КОД события: 0 Дата: 03.11.2011 Время: 08:00:00 Пользователь: н / Д Компьютер: QA-IIS-01 Описание: Не удалось остановить службу.System.Runtime.Remoting.RemotingException: объект '/50e76ee1_3f40_40a1_9311_1256a0375f7d/msjxeib0oy+s0sog1mkeikjd_2.rem' отключен или не существует на сервере.
трассировка стека сервера: в SystemC..CheckDisconnectedOrCreateWellKnownObject (сообщение об ошибке IMessage) в System.Runtime.Remoting.Channels.ChannelServices.SyncDispatchMessage (сообщение об ошибке IMessage)
Исключение перезапускается в [0]: regessage.Ru, IMessage retMsg) в System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (MessageData & msgData, тип Int32) в MyOrg.Service.IServiceHost.Stop () в MyOrg.Workspace.Service.MyAppService.Pro.Service.PronStop (at .Stop).ServiceBase.DeferredStop ()
Для получения дополнительной информации см. Центр справки и поддержки по адресу http://go.microsoft.com/fwlink/events.asp.
Теперь для целей тестирования фактические IServiceHost
просто отправляют записи в журнал событий каксердцебиение и записи, указывающие запуск и остановку иЯ только раскручиваю один домен приложений.
Может показаться, что со временем удаленный прокси-сервер для реализации IServiceHost
в основном домене приложения службы по умолчанию потерял связь с другим концом созданного домена..
Может кто-нибудь объяснить, почему это происходит, или предложить лучший способ для домена по умолчанию попросить сгенерированные домены завершить работу аккуратно?