Запуск службы Topshelf с использованием ConfigureServiceInIsolation - Generic Host

Я разрабатываю очень простое решение Generic Host, которое позволит нам размещать сборки как службы Windows (ala NServiceBus). Я сталкиваюсь со следующим исключением (похожим на комментарии, упомянутые в Dru's сообщение в блоге). Мне нужно, чтобы это работало, чтобы я мог размещать службы в разных доменах приложений.

«Введите« MyProject.WindowsServices.GenericHost.Program + ‹> c__DisplayClass5» в сборке «MyProject.WindowsServices.GenericHost, Version = 1.0.0.0, Culture = нейтральный, PublicKeyToken = null» не помечен как сериализуемый ».

Я использую двоичные файлы Topshelf 1.0 RC, доступные по ссылке для загрузки на домашней странице topshelf (topshelf-project.com). Я пробовал последнюю сборку (29.07.2010), и сборки доступны для загрузки из кода Google и github! Я не могу заставить их работать на меня!

Это работает в библиотеке NServiceBus с более старой версией Topshelf (dll имеет версию 0.8.0.96). С некоторыми незначительными изменениями кода в том, что у меня ниже (используйте CreateServiceLocator вместо HowToBuildService), он работает для меня с этими старыми двоичными файлами, но я бы предпочел придерживаться последнего кода, чтобы воспользоваться всеми запланированными исправлениями или улучшениями.

Вот мой код.

static void Main(string[] args)
{
    ArgumentParser arguments = new ArgumentParser(args);
    string configFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
        arguments.ServiceType.Assembly.ManifestModule.Name + ".config");

    RunConfiguration cfg = RunnerConfigurator.New(x =>
    {
        x.SetServiceName(arguments.ServiceName);
        x.SetDisplayName(arguments.DisplayName);
        x.SetDescription(arguments.Description);

        if (string.IsNullOrEmpty(arguments.UserName))
        {
            x.RunAsLocalSystem();
        }
        else
        {
            x.RunAs(arguments.UserName, arguments.Password);
        }

        x.ConfigureServiceInIsolation<GenericHost>(c =>
        {
            c.ConfigurationFile(configFile);
            c.Named(arguments.ServiceType.AssemblyQualifiedName);
            c.HowToBuildService(name => new GenericHost(arguments.ServiceType));
            c.WhenStarted(tc => tc.Start());
            c.WhenStopped(tc => tc.Stop());
        });
    });

    Runner.Host(cfg, args);
}

Также следует отметить, что мой класс GenericHost и класс, определенный с помощью arguments.ServiceType, реализуют MarshalByRefObject, и я также сделал эти классы сериализуемыми, чтобы посмотреть, поможет ли это. Проблема заключается не в этих классах. Похоже, он жалуется на анонимный тип, сгенерированный компилятором C # для одного или нескольких настроенных мною лямбда-выражений.

Кто-нибудь еще видит эту проблему с использованием ConfigureServiceInIsolation ()? Если нет, то кто-нибудь знает, что мне здесь не хватает? Дайте мне знать, если вам понадобится дополнительная информация, например трассировка стека или другой код.


person Sam    schedule 29.07.2010    source источник


Ответы (1)


Если вы используете только одну службу внутри хоста, я бы удалил «InIsolation». Это работает неправильно, но в будущей версии TopShelf (в настоящее время мы работаем над этим), я думаю, у нас есть лучший ответ на эту проблему. Вдобавок к возможности просто перетаскивать файлы на хост и автоматически запускать вашу службу в новом домене приложений.

Я бы сказал, что это относится к проблеме знания, и если нет веской причины для использования InIsolation, избегайте ее на данный момент. Вы не можете маршалировать лямбда-выражения через барьеры домена приложения, отсюда и проблема, с которой вы сталкиваетесь. Если проблема InIsolation достаточно важна, я могу изучить попытки исправить это в сравнении с графиком, прежде чем мы планируем выпустить новейшую версию. [Вы можете скачать последнюю версию dev. бит отсюда: http://github.com/legomaster/Topshelf - предупреждение, мы все еще находится в активной разработке, но я думаю, что все основные ошибки устранены].

Если вы хотите обсудить это дальше, возможно, проще всего разместить запись в списке MassTransit, куда смотрят все разработчики: http://groups.google.com/group/masstransit-discuss

Надеюсь, это поможет!

person Travis    schedule 29.07.2010
comment
Спасибо за ответ, Трэвис! Похоже, что в будущих версиях будет что-то вроде универсального хоста uber. Добавление файлов для запуска служб Windows было бы очень крутой функцией. А пока я посмотрю, смогу ли я что-нибудь настроить без части InIsolation. Я могу просто вернуться к использованию настраиваемого исполняемого файла для каждой службы, это будет подходящим краткосрочным решением. Есть идеи, когда будет готова следующая версия? - person Sam; 30.07.2010
comment
Я планировал выпустить его в октябре 2010 года, чтобы соответствовать моему внутреннему выпуску. Я ожидаю, что мы все равно уложимся в этот срок, даже несмотря на то, что наши заинтересованные стороны отодвинули мой крайний срок. - person Travis; 31.07.2010
comment
Как только мы все это выпустим, мы будем работать с Уди, чтобы также включить это в основную ветку NServiceBus. Так что, если вы заставите его работать без Isolation, это может послужить вам просто сидением на нем, пока Уди не смешает все новые биты. Но это полностью зависит от вас. Я знаю, что Уди просит у нас еще несколько функций, которые, я надеюсь, мы сможем реализовать в этом году. - person Travis; 31.07.2010
comment
Я упростил свою реализацию, чтобы иметь только исполняемый файл для каждой службы. Если оставить его сейчас на верхней полке, его будет проще обновить позже. В любом случае, я буду следить за следующей версией примерно в октябре и посмотрю, сможем ли мы превратить ее в итерацию примерно к тому времени! Спасибо еще раз. - person Sam; 02.08.2010