【问题标题】:WCF Service Reference in ASP.net Page - When to Dispose?ASP.net 页面中的 WCF 服务参考 - 何时处置?
【发布时间】:2010-08-31 16:44:55
【问题描述】:

我有一个 ASP.net 页面,它正在创建对 WCF 服务的服务引用并在我的页面中的多个位置进行调用。我在 Page_Load 中实例化服务引用并有一个实例变量来存储它:

private FooClient _serviceClient;

protected void Page_Load(object sender, EventArgs e)
{
    _serviceClient = nwe FooClient();
    _serviceClient.GetAllFoos();
}

protected void btnSave_Click(object sender, EventArgs e)
{
    _serviceClient.SaveFoo();
}

我刚刚发现,当我使用完服务引用后,我需要处理它,否则连接将保持活动状态,如果我达到最大连接数,则会阻止传入连接。处理这些参考资料的最佳地点在哪里?我正在考虑在 OnUnLoad 事件中执行此操作。

有更好的方法吗?

【问题讨论】:

    标签: asp.net wcf


    【解决方案1】:

    就我个人而言,我会在需要时打开FooClient,所以不是Page_Load 中,而是在执行Web 服务调用的方法中。这样,您就可以确切地知道它会发生什么。我通常采取以下方法:

    var client = OpenClient();
    try
    {
        // Perform operation(s) on client.
    }
    finally
    {
        CloseClient(client);
    }
    

    这样,无论发生什么,您都可以确保关闭代理(如果需要捕获异常,只需添加一个 catch 子句)。 CloseClient 方法应该类似于 PaulStack 的答案。

    这样做的另一个好处是多个呼叫不会相互干扰。假设其中一个 Web 服务调用导致意外异常。客户端通道现在处于故障状态,因此无法用于任何其他调用。

    第三,假设确实发生了您无法捕获或不想捕获的异常,我不确定Page_Unload 是否被实际调用(我不知道在该事件中将调用哪个页面方法)。这也会使连接保持打开状态。

    【讨论】:

      【解决方案2】:

      根据MSDN文档和个人经验做如下操作:

       try
      {
          ...
          client.Close();
      }
      catch (CommunicationException e)
      {
          ...
          client.Abort();
      }
      catch (TimeoutException e)
      {
          ...
          client.Abort();
      }
      catch (Exception e)
      {
          ...
          client.Abort();
          throw;
      }
      

      这将允许在必要时正确关闭或中止服务,而不是让它们在预定义的时间被处理 - 只要你确定必须保持连接打开。我个人不喜欢从 IDisposable 继承,因为它的性能很重

      【讨论】:

      • 所以你建议我在我需要访问数据的每个方法中打开一个通道?这在性能上似乎相当沉重。
      • @Dismissile - 为什么要保持连接打开而不是在需要时打开它?如果不使用数据库,您会保持与数据库的连接吗?当然,目标是尽可能保持连接免费使用,因此只需在必要时打开。WCF 服务也可以在 Dispose() 上引发异常,因此垃圾收集器将不得不清理连接。如果代码看起来很难看,我确定可以对其进行重构以保持代码干燥
      • @Ronald Wildenberg 我指的是在 WCF 应用程序中实现 IDisposable 可能意味着当调用 Dispose 方法时可能不会被调用,因此它仍然需要垃圾收集 - 因此它的实现是不必要。我们可以解决这个问题的方法是重写 IDisposable 方法,然后从中调用关闭或中止
      • 我不会永远保持连接打开。我在页面加载时打开它。调用一些方法,当页面被卸载时,我想确保它被处理掉。我可能有以下三种方法:GetAllFoos()、GetAllBars() & GetAllOthers()。这些方法中的每一个都需要使用 WCF 服务。我应该在需要访问服务的每个方法中打开和处置吗?
      • 在我看来是的 - 没有办法确定我们可以依赖调用 Page UnLoad 或调用可以处理服务的生命周期方法。
      猜你喜欢
      • 2015-04-09
      • 1970-01-01
      • 2021-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多