【问题标题】:Running Topshelf service using ConfigureServiceInIsolation - Generic Host使用 ConfigureServiceInIsolation 运行 Topshelf 服务 - 通用主机
【发布时间】:2010-07-29 02:11:30
【问题描述】:

我正在开发一个非常简单的通用主机解决方案,它允许我们将程序集作为 Windows 服务(ala NServiceBus)托管。我遇到了以下异常(类似于 Dru blog post 中提到的 cmets)。我需要它来工作,以便我可以在不同的 AppDomain 中托管服务。

“程序集 'MyProject.WindowsServices.GenericHost, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' 中的类型 'MyProject.WindowsServices.GenericHost.Program+c__DisplayClass5' 未标记为可序列化。”

我正在使用 Topshelf 1.0 RC 二进制文件,可从 topshelf 主页 (topshelf-project.com) 上的下载链接获得。我已经尝试了最新的构建(29/07/2010),并且可以从谷歌代码和 github 下载构建!我不能让他们中的任何一个为我工作!

这适用于旧版 Topshelf 的 NServiceBus 库(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,我还使这些类 Serializable 看看是否有帮助。虽然不是这些类导致了问题,但它似乎在抱怨 C# 编译器为我配置的一个或多个 lambda 生成的匿名类型。

还有其他人在使用 ConfigureServiceInIsolation() 时看到这个问题吗?如果没有,有人知道我在这里缺少什么吗?如果您需要更多信息,请告诉我,例如堆栈跟踪或更多代码。

【问题讨论】:

    标签: c# .net windows-services appdomain topshelf


    【解决方案1】:

    如果您只在主机内使用一项服务,我会删除“InIsolation”。它不能正常工作,但在 TopShelf 的未来版本(我们目前正在研究它)中,我认为我们对这个问题有更好的答案。除了将文件拖放到主机中并自动在新的 AppDomain 中启动您的服务的能力之外。

    我会说这属于已知问题,除非有令人信服的理由使用 InIsolation,否则暂时避免使用它。您无法跨应用程序域障碍编组 lambda 表达式,因此您会看到问题。如果 InIsolation 问题足够重要,我可以在我们计划发布最新版本之前研究解决该问题的努力与时间表。 [您可以获取最新的开发。来自这里的位:http://github.com/legomaster/Topshelf - 警告,我们仍在积极开发中,但我认为所有主要错误现在都已被压扁]。

    如果您想进一步讨论这个问题,最好在所有开发人员都在关注的 MassTransit 列表上发帖:http://groups.google.com/group/masstransit-discuss

    我希望这会有所帮助!

    【讨论】:

    • 感谢您回答特拉维斯!听起来未来的版本将有一种超级通用主机。将文件放入以运行 Windows 服务将是一个非常酷的功能。现在,我将看看是否可以在没有 InIsolation 部分的情况下进行设置。我可能只是切换回每个服务都有一个自定义可执行文件,这作为一个短期解决方案很好。知道下一个版本什么时候可以准备好?
    • 我将它定为 2010 年 10 月发布,以满足我的内部发布。我预计即使我的截止日期已被我们的利益相关者推迟,我们仍能按时完成。
    • 一旦我们发布了这一切,我们将与 Udi 合作,将其也纳入主线 NServiceBus。因此,如果你让它在没有隔离的情况下工作,它可能会为你服务,直到 Udi 混合所有新的部分。但这完全取决于你。我知道 Udi 要求我们提供更多功能,我希望我们能够在今年提供这些功能。
    • 我现在已经简化了我的实现,只为每个服务提供一个可执行文件。现在将其保持在“顶层”将使以后的升级更容易。无论如何,我会密切关注 10 月左右的下一个版本,看看我们是否可以在那个时候将它变成一个迭代!再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多