Проблема связи между AppDomain - PullRequest
13 голосов
/ 11 марта 2011

Я занимаюсь разработкой службы 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 в основном домене приложения службы по умолчанию потерял связь с другим концом созданного домена..

Может кто-нибудь объяснить, почему это происходит, или предложить лучший способ для домена по умолчанию попросить сгенерированные домены завершить работу аккуратно?

1 Ответ

25 голосов
/ 11 марта 2011

Укол в темноте здесь.Срок действия аренды удаленного объекта истекает?Посмотрите на MarshalByRefObject.InitializeLifetimeService .Чтобы сделать объект постоянным, просто переопределите и верните null.

public override object InitializeLifetimeService()
{
    // returning null here will prevent the lease manager
    // from deleting the object.
    return null;
}
...