【问题标题】:Why would a WCF webservice hosted in IIS randomly stop responding?为什么托管在 IIS 中的 WCF Web 服务会随机停止响应?
【发布时间】:2009-10-09 12:37:25
【问题描述】:

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

【问题讨论】:

  • 我怀疑是 WCF - 更有可能是 IIS 和 ASP.NET 应用程序池阻止了您的通信。 WCF 的 IIS 托管是一个......次优的解决方案 - 我总是在我自己的 NT 服务或控制台应用程序中托管 WCF 服务。
  • 我有点困惑。您的 MVC 应用程序是否使用托管在另一个 IIS 实例中的 WCF 服务?
  • marc_s 关于为什么在 IIS 中托管 WCF 不是最佳选择,您是否有更多信息?我们必须在客户的站点部署这项服务,让他们同意的最简单方法似乎是托管在 IIS 中。
  • d91-jal 是 .. MVC 网站使用 WCF 服务,该服务将托管在多个远程(客户)网站上。
  • 嗯,两个主要原因:1) 它需要更多的功率,因为​​ IIS 将为它需要服务的每个传入请求创建一个新的 ServiceHost(您的自托管应用程序不需要),并且2) 如果您在具有其他 ASP.NET 应用程序的 IIS 环境中托管 WCF 服务,您可能会受到 ASP.NET 应用程序池被回收的副作用的影响。使用 WCF 的单独应用程序池可以更干净地完成它 - 但通常情况下,它没有完成。

标签: asp.net-mvc wcf timeout


【解决方案1】:

当您使用完 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 的信息。

【讨论】:

  • 马克 - 你能推荐任何关于这个主题的好读物吗?此外,在以某种通用方式包装此 try/finally/try 时,是否有任何最佳实践?似乎有很多可以简化的样板代码。
  • 这个链接很方便:slideshare.net/blowdart/10-tricks-and-tips-for-wcf .. 幻灯片 15 显示了类似的处理方法。
  • 上次我不得不处理这个问题时,我编写了一个可重用的方法,它完成了所有这些样板代码并将 Func 作为输入参数,这样我就可以将 Func 传递给方法并进行安全处理客户的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-18
  • 2011-11-25
  • 1970-01-01
  • 1970-01-01
  • 2022-12-13
  • 1970-01-01
相关资源
最近更新 更多