为什么WCF不支持服务端超时?

Dav*_*dro 20 .net wcf timeout

我们最近发现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>
Run Code Online (Sandbox Code Playgroud)

我们的测试服务实现如下所示:

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};
    }
}
Run Code Online (Sandbox Code Playgroud)

使用netNamedPipeBinding和netTcpBinding,我们的客户端应用程序将在5秒后超时,但该服务将无限期地继续运行.

这带来了我的问题 - 这是一个错误吗?是否存在特定原因导致WCF如果运行时间超过预期而不想超时服务?

从我的角度来看,其中一些潜在的负面问题包括:

  1. 服务实例的默认限制为10.因此,如果您的服务中的错误代码永远运行且被命中10次,则您的服务将完全关闭; 没有新的连接被接受.
  2. 对服务永远运行这一事实没有任何可见性 - 缺少自定义日志记录或可能使用性能计数器
  3. 如果没有其他机制来超时操作,则服务调用正在使用的任何资源都可以无限期保留(例如,SQL行,页和表锁).

Jef*_*tin 9

如果你有永远运行的坏代码,那么将它计时可能只会让事情变得更糟. 尽可能修复坏代码! 见埃里克利珀的文章中,小心那个斧头,这些各种各样的情况.

如果正在开发中,您可能希望尝试在服务实现中设置System.Threading.Timer调用serviceCallThread.Abort().但是,确保在返回之前已经彻底解除了计时器 - 由于并发问题的混合,没有拥有服务调用到达的线程,奇怪的行为和问题,这种方法非常容易出错.ThreadAbortException埃里克解释了盲目地终止在杂草中消失的代码.

  • 是的我的意思是摆脱运行时间过长的代码是有意义的.但是,当你不期望它永远运行时呢?您如何知道服务仍在执行以及当所有客户端长时间断开连接时它处于什么状态? (2认同)