ASP.net页面中的WCF服务引用-何时处置?

ASP.net页面中的WCF服务引用-何时处置?,asp.net,wcf,Asp.net,Wcf,我有一个ASP.net页面,该页面正在创建对WCF服务的服务引用,并在页面中的多个位置进行调用。我在Page_Load中实例化服务引用,并使用实例变量存储它: private FooClient _serviceClient; protected void Page_Load(object sender, EventArgs e) { _serviceClient = nwe FooClient(); _serviceClient.GetAllFoos(); } protec

我有一个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活动上做这件事


有更好的方法吗?

根据MSDN文档和个人经验,执行以下操作:

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

这将允许在必要时正确关闭或终止服务,而不是让它们在预定义的时间被处理—只在您必须打开连接的时候保持连接。就我个人而言,我不喜欢继承IDisposable,因为它的性能非常高。就我个人而言,我会在需要时打开
FooClient
,所以不是在
Page\u Load
中,而是在进行web服务调用的方法中。这样,你就知道它到底发生了什么。我通常采取以下方法:

var client = OpenClient();
try
{
    // Perform operation(s) on client.
}
finally
{
    CloseClient(client);
}
这样,无论发生什么情况,都可以确保关闭代理(如果需要捕获异常,只需添加一个catch子句)。
CloseClient
方法应该与PaulStack的答案中的方法类似

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


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

所以你建议我在访问数据所需的每种方法中打开一个通道?这在性能上似乎相当沉重。@dismissible-为什么要保持连接打开,而不是在需要时打开它?如果数据库未被使用,您会保持与数据库的连接处于打开状态吗?当然,其目的是在可能的情况下保持连接的可用性,因此在必要时只需打开即可。此外,WCF服务可能会在Dispose()上引发异常,因此垃圾收集器必须清理连接。如果代码看起来很难看,我相信它可以被重新分解以保留代码DRY@RonaldWildenberg I所指的事实是,在WCF应用程序中实现IDisposable可能意味着在调用Dispose方法时可能不会调用它,因此它仍然需要垃圾收集,因此不需要实现它。我们可以绕过这个问题的方法是重写IDisposable方法,然后从itI调用close或abort。我不会永远保持连接打开。我在页面加载时打开它。调用一些方法,当页面被卸载时,我想确保它被处理掉。我可能有以下三种方法:GetAllFoos()、GetAllBars()和GetAllOthers()。每种方法都需要使用WCF服务。我是否应该在需要访问服务的每个方法中打开和释放?我认为是的-我们无法确定是否可以依赖于调用页面卸载或调用生命周期方法来释放服务。