我有一个相当简单的WCF服务,可以为一堆智能客户端执行单向文件同步。我注意到,当呼叫期间出现网络或服务中断时,客户端将无法与服务器通信,直到整个应用程序重新启动。
该服务使用BasicHttpBinding
运行,并使用transferMode="Streamed"
和messageEncoding="Mtom"
与IIS6(.svc页面)一起托管。该服务配置为使用默认的InstanceContextMode(我认为它是Per Call?)和ConcurrencyMode = Single。它使用的是默认的限制行为,但我处于一个孤立的测试环境中,没有其他人在打击它。
客户端是Windows服务。我正在使用此ServiceProxyHelper来确保在Close()
'时正确联系Abort()
'或Dispose()
,尽管没有会话,所以我不认为这甚至很重要。发生错误时,将丢弃Client对象,然后超出范围。检测到异常后,服务稍稍等待,然后创建一个新的客户端对象并再次尝试。所以它应该从失败中恢复,但由于某种原因,所有后续的服务调用都会失败。
我可以通过启动客户端,允许它传输一些文件,然后重置服务器来可靠地重现这一点。首先,客户端通常显示“Service is Too Busy”错误(映射到应用程序重新启动期间获得的IIS 503错误)。之后,所有后续的服务调用都会超时。据我所知,客户甚至没有尝试过这些电话。我启用了跟踪,我看到的是:超时错误,后跟“无法通过HTTP发送请求消息”警告,然后是另一个超时错误。
疯狂的是,当我将客户端配置为使用Fiddler(端口8888)作为app.config中的代理时,一切都按预期工作。所以Fiddler作为代理人正在关闭或完成WCF本身不具备的某种连接。
思想?
编辑2009-10-30 8:54 PM :将服务属性更改为:InstanceContextMode = Single和ConcurrencyMode = Multiple。没有区别。
答案 0 :(得分:2)
那很痛苦。它花了我很长时间,但最后我把注意力与代理与没有运行之间的差异归零,并开始探讨<system.net>
设置。事实证明,将此配置位添加到客户端可以解决问题:
<system.net>
<settings>
<servicePointManager expect100Continue="false" />
</settings>
</system.net>
有人可以解释发生了什么吗?为什么此设置会导致WCF客户端在服务中断时无法挂起?
答案 1 :(得分:0)
您确定这不是客户端问题。如果您的Windows服务正在从主要的单独线程上进行WCF调用,并且您在子线程上发生了未处理的异常...调用线程可能会也可能不会坐在那里等待永远因为它正在等待该线程返回。
这可以解释为什么服务中存在异常,然后看起来该服务不再调用该服务......它已挂起。
在使用Timers在.NET 2.0 Windows服务中生成进程时,曾经是一个很大的问题。