为什么在IIS中托管的WCF Web服务会随机停止响应?

时间:2009-10-09 12:37:26

标签: asp.net-mvc wcf timeout

这是我第一次尝试使用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()会使对象处于已处置状态。

1 个答案:

答案 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