繁体   English   中英

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

[英]How to detect when a WCF client failed to close properly?

我试图找出我们使用过的一种WCF服务遇到的问题。 它有时会变得无响应,从而使我们依赖该服务的一些内部网站无法使用。

我们怀疑这是因为一个或多个使用网站无法正确关闭连接,因此我们在服务上允许的并发连接数上达到了限制。 但是,由于在多个tfs存储库中有太多存储库,因此我们没有确定哪一个的实用方法。

简而言之,当客户端在wcf代理上调用Close()时,如何从服务中进行检测? 或者,更确切地说,在服务方法完成后,如何检测http连接是否仍处于打开状态?

我没有在本地工作站上创建过测试服务和客户端,并尝试了以下方法:

测试服务:

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

测试客户:

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

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

perfmon性能计数器(添加ServiceModelService 4.0.0.0之后)报告该服务调用甚至在client.Close()执行之前就已完成。 服务调用之后,client.Close()前后的计数器没有变化。

接下来,我尝试监听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
    }
}

但是我放置在事件处理程序中的所有断点都没有遇到。

我还尝试在Global.asax的Session_Start和Session_End事件中放置断点。 Session_Start会触发,但Session_End不会触发(尽管我不知道会话是否与http连接是否存在有关系)。

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

调用服务时应处理异常,否则通道可能无法正常关闭。

例如: 从这里

    WCFServiceClient c = new WCFServiceClient();

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

(如果需要,还有一个使用“ using”的示例)。

也可以在这里看看。

暂无
暂无

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

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