我们最近发现,WCF不支持在服务端(注意,是服务端,而不是客户端)超时操作。虽然客户端在指定时间后会断开连接,但我们的测试表明,在netNamedPipeBinding、netTcpBinding和basicHttpBinding中,我们指定的任何超时都不会导致服务操作停止一旦被调用。以下是我们尝试过的具体绑定配置:
<bindings>
<netNamedPipeBinding>
<binding name="TestServiceBindingConfigurationNamedPipe"
receiveTimeout="00:00:05"
sendTimeout="00:00:05"
closeTimeout="00:00:05"
openTimeout="00:00:05" />
</netNamedPipeBinding>
<netTcpBinding>
<binding name="TestServiceBindingConfigurationTcp"
receiveTimeout="00:00:05"
sendTimeout="00:00:05"
closeTimeout="00:00:05"
openTimeout="00:00:05" />
</netTcpBinding>
<basicHttpBinding>
<binding name="TestServiceBindingConfigurationBasicHttp"
receiveTimeout="00:00:05"
sendTimeout="00:00:05"
closeTimeout="00:00:05"
openTimeout="00:00:05" />
</basicHttpBinding>
</bindings>
我们的测试服务实现如下:
public class TestServiceImpl : ITestService
{
public TestResult TestIt(TestArgs args)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
// this is a contrived example, but it shows that WCF never stops this thread
while (true)
{
Console.WriteLine("{0}> I'm running forever...", stopwatch.Elapsed);
}
return new TestResult {Result = "Args were " + args.Args};
}
}
使用netNamedPipeBinding和netTcpBinding,我们的客户端应用程序在5秒后会超时,但服务将继续无限期运行。
这引出了我的问题 - 这是一个错误吗?WCF是否有特定的原因不想超时运行时间长于预期的服务?
从我的角度来看,一些可能存在的负面影响包括:
- 服务实例的默认限制为10。因此,如果您的服务中有永远运行的错误代码,并且它被调用了10次,您的服务将完全关闭;不接受任何新连接。
- 除非进行自定义日志记录或可能使用性能计数器,否则没有任何可见性表明服务正在永久运行。
- 如果没有其他机制超时操作,则正在使用服务调用的任何资源可能会无限期保持(例如SQL行、页和表锁)。