代码之家  ›  专栏  ›  技术社区  ›  Sandor Drieënhuizen

wcf/s arparch:请求中的第一个调用之后,基础ISession将关闭

  •  2
  • Sandor Drieënhuizen  · 技术社区  · 14 年前

    我知道不赞成在sa中使用wcf,因为它将转移到sa contrib。但在这之前,我想我必须利用南澳大利亚的支持。

    也就是说,在调用wcf服务之后,底层nhibernate会话关闭有问题。我的存储库的dbcontext.session在第一次调用后关闭,因此在单个http请求期间我不能多次调用我的服务。

    我已经在项目中基于northwind示例应用程序设置了wcf。示例只在每个请求中调用一次wcf服务,因此不会出现此问题。但是,通过复制 区域控制器:

    territories=territorieswcfservice.getterritories();

    这抛出一个objectDisposedException:“会话已关闭!对象 名称:“ISession”。

    有什么想法吗?

    2 回复  |  直到 14 年前
        1
  •  3
  •   Sandor Drieënhuizen    14 年前

    我设法解决了。

    通过检查sharparch.wcf源代码,我发现在发送wcf服务响应之前,它总是关闭所有nhibernate会话。这本身就是一件好事。

    另外,我发现我的客户端代理工厂在每个web请求中只触发一次,而第二个服务调用应该会产生一个新的代理实例。结果是,第二个服务调用将失败,因为底层的nhibernate会话已经关闭。我用 Castle.Core.过渡属性 ,这将生命周期管理留给创建客户机的工厂。其结果是每次请求代理时都会调用代理工厂。

    其次,我必须这样注册代理(在 组件注册器 班级):

    container.AddFacility("WcfSessionFacility", new WcfSessionFacility());
    
    container.Kernel.AddComponentWithExtendedProperties(
        "AccountService",
        typeof(IAccountService),
        typeof(AccountServiceClient),
        new Dictionary<string, object>()
            {
                { WcfSessionFacility.ManageWcfSessionsKey, true }
            });
    

    这个 WCF会话设施 根据客户机的状态管理其关闭/中止。这可以确保每当客户机代理被破坏时,客户机通道都是关闭的,因此我们不需要将调用放入try catch块中。

    像我一样,您可能会考虑在添加组件而不是使用属性时配置生存期管理,但显然没有合适的 AddComponentWithExtendedProperties 这就允许了。

        2
  •  1
  •   Michael Maddox    14 年前

    我对sharparchitecture不太熟悉,但似乎您至少有两个选择:

    1. 在客户端,在 先打个电话,换个WCF 做第二个之前的服务 打电话,这样就有了新的任务。

    2. 使WCF服务更智能 关于会话处理 可以保持会话打开的时间更长。 有多种方法可以做到这一点 可能是因为 wcf服务中新逻辑的数量,但它应该 完全可行。