【问题标题】:WCF Client hang on service interruptionWCF 客户端在服务中断时挂起
【发布时间】:2009-10-29 22:31:20
【问题描述】:

我有一个相当简单的 WCF 服务,它为一组智能客户端执行单向文件同步。我注意到,当通话过程中出现网络或服务中断时,客户端将无法与服务器通信,直到整个应用程序重新启动。

该服务使用BasicHttpBinding 运行,并使用transferMode="Streamed"messageEncoding="Mtom" 托管在IIS6(一个.svc 页面)上。该服务被配置为使用默认的 InstanceContextMode(我认为它是 Per Call?)和 ConcurrencyMode=Single。它使用默认的节流行为,但我处于一个没有其他人可以访问的隔离测试环境中。

客户端是 Windows 服务。我正在使用这个ServiceProxyHelper 来确保Close()'d 或Abort()'d 在Dispose()'d 时正确连接,尽管没有会话,所以我认为这甚至不重要。发生错误时,客户端对象被释放,然后超出范围。检测到异常后,服务稍等片刻,然后创建一个新的客户端对象并重试。所以它应该从失败中恢复,但由于某种原因,所有后续调用服务都失败了。

我可以通过启动客户端来可靠地重现这一点,允许它传输一些文件,然后 iis 重置服务器。首先,客户端通常会显示“服务太忙”错误(映射到您在应用重新启动期间遇到的 IIS 503 错误)。之后,对服务的所有后续调用都会超时。据我所知,客户甚至没有尝试拨打电话。我启用了跟踪,我看到的是:超时错误,然后是“无法通过 HTTP 发送请求消息”警告,然后是另一个超时错误。

疯狂的是,当我将客户端配置为使用 Fiddler(端口 8888)作为 app.config 中的代理时,一切都按预期工作。所以不知何故,作为代理的 Fiddler 正在关闭或完成某种 WCF 本身没有的连接。

想法?

编辑 2009-10-30 8:54PM:将服务属性更改为:InstanceContextMode=Single 和 ConcurrencyMode=Multiple。没有区别。

【问题讨论】:

    标签: wcf


    【解决方案1】:

    那很痛苦。我花了很长时间,但最终我确定了使用代理运行与不使用代理之间的区别,并开始研究<system.net> 设置。事实证明,将这个配置位添加到客户端可以解决问题:

      <system.net>
        <settings>
          <servicePointManager expect100Continue="false" />
        </settings>
      </system.net>
    

    有人可以解释发生了什么吗?当服务中断时,为什么此设置会导致 WCF 客户端不可挽回地挂起?

    【讨论】:

    【解决方案2】:

    您确定这不是客户端问题吗?如果您的 Windows 服务在与主线程不同的线程上进行 WCF 调用,并且您在子线程上发生了未处理的异常...调用线程可能会或可能不会坐在那里等待永远 strong> 因为它正在等待该线程返回。

    这可以解释为什么服务内部存在异常,然后看起来服务不再调用服务......它已挂起。

    在 .NET 2.0 Windows 服务中使用计时器生成进程时曾经是一个大问题。

    【讨论】:

    • 我确实认为这是一个客户端问题,但我不认为这是线程问题,尽管您是对的,这些客户端是在与主线程不同的线程上生成的。我使用的是 BackgroundWorker 而不是线程,并且如果线程出错,我已经连接到 RunWorkerCompleted 事件以重新启动。我看到这个逻辑正在执行,我看到工作人员再次启动并尝试与服务通信。失败的正是这些后续调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    • 1970-01-01
    • 2019-01-29
    相关资源
    最近更新 更多