这是我第一次尝试使用WCF,因此这种方法可能存在根本性的错误 - 如果是这样,我很乐意切换到不同的模型。快速浏览一下,我认为this question的答案会奏效,但我的情况似乎有所不同。
我有一个ASP.NET MVC网站,其中控制器通过中间存储库访问WCF客户端类。存储库只是WCF客户端的包装器,它实例化一次并设置正确的端点地址。
public class WcfRepository : IRepository
{
private MyWCFServiceClient client;
public WcfRepository()
{
client = new MyWCFServiceClient();
}
public bool MyMethod1()
{
return client.MyMethod1();
}
... etc
}
我可以访问网站上的不同页面,直到WCF服务开始超时的看似随机的点。无论我称之为哪种方法都没关系 - 它在不同的方法上超时。我在主机WCF服务的IIS机器上看不到任何异常;事件日志有空。像GetCustomerByName()
之类的简单方法在两分钟之前工作将不再如此,我认为它更多地与WCF通信而不是服务本身有关。
如果我在其中一个超时发生后尝试使用WCF测试客户端,它也将失败。但是,如果我等待一段时间(并选择“开始新的代理”),那么事情就会再次发挥作用。
我很困惑 - 每次我想在我的存储库中使用它时,我是否应该创建WCF客户端的新实例?还有其他方法我应该使用客户端吗?在Open()/Close()
中包含每个调用都不起作用,因为第一次调用Close()
会使对象处于已处置状态。
答案 0 :(得分:2)
完成WCF客户端后,必须明确关闭它,否则它将保持对服务的“连接”开放,并且(可配置)限制可以有多少并发连接。
尽管可以调整该限制,但正确的解决方案是创建一个新的WCF客户端,在其上调用一个或多个方法,并在完成后再次关闭它。这被认为是最佳做法,应该巧妙地避免您目前遇到的那类问题。
这意味着你的实现应该是这样的:
public class WcfRepository : IRepository
{
public bool MyMethod1()
{
var client = new MyWCFServiceClient();
try
{
return client.MyMethod1();
}
finally
{
try
{
client.Close();
}
catch(CommunicationException)
{
// handle exception here
}
catch(TimeoutException)
{
// handle exception here
}
}
}
... etc
}
注意讨厌的try / finally结构,这是必要的,因为Close可能会抛出。详细了解此here。