Asp.net mvc 为什么IIS中托管的WCF Web服务会随机停止响应?
这是我第一次尝试使用WCF,所以这种方法可能有一些根本性的错误——如果是这样,我很乐意切换到另一种模式。一眼望去,我以为这个问题的答案会奏效,但我的情况似乎有所不同 我有一个ASP.NET MVC网站,控制器通过中间存储库访问WCF客户端类。存储库只是WCF客户机的包装器,它对其进行一次实例化并设置正确的端点地址Asp.net mvc 为什么IIS中托管的WCF Web服务会随机停止响应?,asp.net-mvc,wcf,timeout,Asp.net Mvc,Wcf,Timeout,这是我第一次尝试使用WCF,所以这种方法可能有一些根本性的错误——如果是这样,我很乐意切换到另一种模式。一眼望去,我以为这个问题的答案会奏效,但我的情况似乎有所不同 我有一个ASP.NET MVC网站,控制器通过中间存储库访问WCF客户端类。存储库只是WCF客户机的包装器,它对其进行一次实例化并设置正确的端点地址 public class WcfRepository : IRepository { private MyWCFServiceClient client; publi
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客户端时,我是否应该创建一个新的WCF客户端实例?是否有其他方法可以使用客户端?在
Open()/Close()
中包装每个调用也不起作用,因为对Close()
的第一次调用会将对象置于已处置状态。使用完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可能抛出。了解更多信息。我怀疑是WCF——更有可能是IIS和ASP.NET应用程序池阻碍了您的通信。WCF的IIS宿主是一个。。。。。次优解决方案-我总是在自己的NT服务或控制台应用程序中托管WCF服务。我有点困惑。您的MVC应用程序是否使用了托管在另一个IIS实例中的WCF服务?marc_s您是否有关于为什么在IIS中托管WCF不理想的更多信息?我们必须在客户的站点上部署此服务,让他们同意的最简单方法似乎是在IIS.d91-jal中托管。是的。。MVC网站使用WCF服务,该服务将托管在多个远程(客户)网站上。主要原因有两个:1)它需要更大的功率,因为IIS将为它需要服务的每个传入请求创建一个新的ServiceHost(您的自托管应用程序不需要),2)如果您在IIS环境中使用其他ASP.NET应用程序托管WCF服务,您可能会受到ASP.NET应用程序池回收的副作用的影响。使用单独的WCF应用程序池可以更干净地完成这项工作,但通常情况下,这项工作还没有完成。马克,你能推荐一些关于这个主题的好阅读材料吗?另外,在以某种通用方式包装这个try/finally/try时,是否有最佳实践?似乎有很多样板代码可以简化。这个链接很方便:。。幻灯片15显示了一个类似的处理方法。上次我不得不处理这个问题时,我编写了一个可重用的方法,它完成了所有的样板代码,并将Func作为输入参数,这样我就可以将Func传递给该方法,并安全地处理客户端。