Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
598 views
in Technique[技术] by (71.8m points)

.net - Why doesn’t WCF support service-side timeouts?

We’ve recently discovered that WCF does not support timing out operations on the service side (note, service side, not client side). While the client disconnects after the specified time, our testing has shown that for netNamedPipeBinding, netTcpBinding and basicHttpBinding, no timeout that we specify will cause the service operation to stop once it has been invoked. Below are the specific binding configurations that we tried:

<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>

Our test service implementation looks like this:

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};
    }
}

Using netNamedPipeBinding and netTcpBinding, our client app would timeout after 5 seconds, but the service would continue running indefinitely.

That brings to my question(s) – is this a bug? Is there a specific reason why WCF would not want to time out services if they run for longer than expected?

From my perspective, some of the potential negative issues with this include:

  1. The default limit of service instances is 10. Therefore, if you have bad code in your service that runs forever and it is hit 10 times, your service will completely shut down; no new connections are accepted.
  2. There isn’t any visibility into the fact that services are running forever - short of custom logging or possibly using performance counters
  3. Any resources that are being used by the service call may be held indefinitely (SQL row, page, and table locks, for example) if there are no other mechanisms to timeout the operation.
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If you have bad code that runs forever, timing it out may only make things worse. Fix the bad code if at all possible! See Eric Lippert's article, Careful with that axe, about these sorts of situations.

If this is in development, you might want to try setting up a System.Threading.Timer that calls serviceCallThread.Abort() within your service implementation. However, be sure you've disarmed the timer thoroughly before you return -- this approach is insanely error-prone, due to a mix of concurrency issues, not owning the thread on which the service call arrives, oddball behavior of ThreadAbortException, and the issues Eric explains about blindly terminating code that's gone off in the weeds.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...