简体   繁体   中英

How to detect when a WCF client failed to close properly?

I'm trying to figure out an issue we're having with one of our heavily used WCF services. It occasionally becomes unresponsive, thereby making several of our internal websites which rely on the service unusable.

We suspect it's because one or more of the consuming websites is failing to close connections properly, and so we're hitting a limit on the number of concurrent connections allowed on the service. We have no practical way, however, of determining which one since there are so many across several tfs repositories.

In short, how do you detect from the service when a client has called Close() on the wcf proxy? Or, rather, how do you detect whether or not the http connection is still open after the service method has completed?

I've created a test service and client on my local workstation and tried the following, although none quite worked:

Test Service:

public class Service1 : IService1
{
    public string GetData(int value)
    {
        return string.Format("You entered: {0}", value);
    }
}

Test Client:

class Program
{
    static void Main(string[] args)
    {
        ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
        Console.WriteLine(client.GetData(0));
        Console.ReadKey();
        client.Close();
        Console.WriteLine("Closed.");
        Console.ReadKey();
    }
}

Running netstat shows that, even after client.Close(), the connection remains open (maybe I'm just misunderstanding the output of netstat).

The perfmon performance counters (after adding ServiceModelService 4.0.0.0) reports that the service call completed even before client.Close() has executed. After the service call, there's no change in the counters before and after client.Close().

Next, I tried listening to the OperationContext.Current.Channel.Closed event (as well as the Closing, and Faulted):

public class Service1 : IService1
{
    public string GetData(int value)
    {
        OperationContext.Current.Channel.Faulted += Channel_Faulted;
        OperationContext.Current.Channel.Closing += Channel_Closing;
        OperationContext.Current.Channel.Closed += Channel_Closed;
        return string.Format("You entered: {0}", value);
    }

    void Channel_Faulted(object sender, EventArgs e)
    {
        // Breakpoint
    }

    void Channel_Closing(object sender, EventArgs e)
    {
        // Breakpoint
    }

    void Channel_Closed(object sender, EventArgs e)
    {
        // Breakpoint
    }
}

But none of the breakpoints I placed in the event handler were ever hit.

I also tried putting breakpoints in the Session_Start and Session_End events in the Global.asax. Session_Start does fire, but Session_End never does (although I don't know whether sessions have anything to do with whether the http connection is alive or not).

I'm somewhat new to wcf (I wrote a couple of very basic services before) so I feel like I'm in a bit over my head on this issue, digging into parts I don't understand (eg, I didn't know OperationContext existed before today).

You should handle exceptions when calling your services or the channels can fail to close properly.

eg: from here :

    WCFServiceClient c = new WCFServiceClient();

    try
    {
            c.HelloWorld();
    }
    catch
    {
            c.Abort();
            throw;
    }
    finally
    {
            c.Close();
    }

(There is also an example with 'using' if preferred).

Also have a look here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM