简体   繁体   English

如何检测WCF客户端何时无法正常关闭?

[英]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. 我试图找出我们使用过的一种WCF服务遇到的问题。 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. 但是,由于在多个tfs存储库中有太多存储库,因此我们没有确定哪一个的实用方法。

In short, how do you detect from the service when a client has called Close() on the wcf proxy? 简而言之,当客户端在wcf代理上调用Close()时,如何从服务中进行检测? Or, rather, how do you detect whether or not the http connection is still open after the service method has completed? 或者,更确切地说,在服务方法完成后,如何检测http连接是否仍处于打开状态?

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). 运行netstat显示,即使在client.Close()之后,连接仍保持打开状态(也许我只是误解了netstat的输出)。

The perfmon performance counters (after adding ServiceModelService 4.0.0.0) reports that the service call completed even before client.Close() has executed. perfmon性能计数器(添加ServiceModelService 4.0.0.0之后)报告该服务调用甚至在client.Close()执行之前就已完成。 After the service call, there's no change in the counters before and after client.Close(). 服务调用之后,client.Close()前后的计数器没有变化。

Next, I tried listening to the OperationContext.Current.Channel.Closed event (as well as the Closing, and Faulted): 接下来,我尝试监听OperationContext.Current.Channel.Closed事件(以及Closing和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. 我还尝试在Global.asax的Session_Start和Session_End事件中放置断点。 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). Session_Start会触发,但Session_End不会触发(尽管我不知道会话是否与http连接是否存在有关系)。

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). 我对wcf有点陌生(我之前写过一些非常基础的服务),所以我觉得在这个问题上我有点不知所措,深入研究了我不了解的部分(例如,我没有知道OperationContext在今天之前存在)。

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). (如果需要,还有一个使用“ using”的示例)。

Also have a look here . 也可以在这里看看。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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