Inter-AppDomain通信问题

Ant*_*nes 13 .net c# remoting windows-services appdomain

我一直在用C#开发Windows服务.

启动时,会为此服务提供一组配置文件路径.对于这些文件中的每一个,服务都将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;
    }
Run Code Online (Sandbox Code Playgroud)

IServiceHost界面是极其复杂的: -

public interface IServiceHost
{
    void Start();
    void Stop();
}
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

OnStop(现在让事情变得简单了同样是直线前进IServiceHost.Stop的阻塞调用).

protected override void OnStop()
{
    foreach (IServiceHost host in serviceHosts)
    {
        host.Stop();
    }
}
Run Code Online (Sandbox Code Playgroud)

这一切都很简单,在开发机器上进行测试时工作正常.然而,在QA中,我在停止时会遇到异常.在开发过程中,我们只是在很短的时间内完成这些工作似乎一切正常.但是在QA中,服务仅每24小时停止一次.在这种情况下,它始终无法正确停止.

以下是事件日志中最终结果的示例: -

事件类型:错误事件源:工作区服务事件类别:无事件ID:0日期:11/03/2011时间:08:00:00用户:N/A计算机:QA-IIS-01描述:无法停止服务.System.Runtime.Remoting.RemotingException:对象'/50e76ee1_3f40_40a1_9311_1256a0375f7d/msjxeib0oy+s0sog1mkeikjd_2.rem'已断开连接或在服务器上不存在.

服务器堆栈跟踪:System.Runtime.Remoting.Channels.ChannelServices.SyncDispatchMessage(IMessage msg)上的System.Runtime.Remoting.Channels.ChannelServices.CheckDisconnectedOrCreateWellKnownObject(IMessage msg)

在[0]处重新抛出异常:位于My.rg.Service的System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&msgData,Int32类型)的System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,IMessage retMsg). System.ServiceProcess.ServiceBase.DeferredStop()中MyOrg.Workspace.Service.MyAppService.OnStop()的IServiceHost.Stop()

有关详细信息,请参阅http://go.microsoft.com/fwlink/events.asp上的"帮助和支持中心" .

现在出于测试目的,实际上IServiceHost只是将条目作为心跳发布到事件日志中,并且条目指示启动和停止,并且我只是启动单个AppDomain.

似乎随着时间的推移,IServiceHost主服务默认应用程序域中的实现者的远程代理与生成的域中的另一端失去了联系.

任何人都可以解释为什么会发生这种情况,或者为默认域提供更好的方法来要求生成的域以整齐的方式关闭?

Jim*_*hel 25

在这里黑暗中刺伤.远程对象的生命周期租约是否到期?查看MarshalByRefObject.InitializeLifetimeService.要使对象持久化,只需覆盖并返回null.

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