如何测试网管服务是否正在监听

时间:2011-12-20 05:15:01

标签: c# wcf named-pipes

如何以编程方式测试以查看特定的网络管道服务是否正在运行和监听,因此我没有得到“没有端点正在侦听......”异常?

例如,如果我有这个代码:

Uri baseAddress = new Uri("http://localhost/something");
var _ServiceHost = new ServiceHost(typeof(Automation), new Uri[] { baseAddress });
NetNamedPipeBinding nnpb = new NetNamedPipeBinding();
_ServiceHost.AddServiceEndpoint(typeof(IAutomation), nnpb, "ImListening");
_ServiceHost.Open();

我想从另一个应用程序与http://localhost/something/ImListening进行通信但是在我想确保正在侦听之前我没有得到异常,或者是测试它的唯一方法的异常?

4 个答案:

答案 0 :(得分:1)

听取异常。那正确的方法。

答案 1 :(得分:1)

异常存在是有原因的,我只会处理异常,只要你处理它,用户就不会得到一个神秘的错误信息,我想这是你想要避免的。

答案 2 :(得分:0)

也许不是最好的方法,但我没有找到另一种使用NetNamedPipe测试端点的方法。

我通常采用这种方法:

    public void IsValid()
    {
        RegisterConfiguration();

        var endPoints = Host.Description.Endpoints;
        if (!endPoints.HasElements())
        {
            throw new NullReferenceException("endpoints (WCF Service).");
        }

        foreach (var item in endPoints)
        {
            var service = new ChannelFactory<ITcoService>(item.Binding, item.Address);
            try
            {
                var client = (IClientChannel)service.CreateChannel();

                try
                {
                    client.Open(TimeSpan.FromSeconds(2));
                    throw new InvalidOperationException(
                        string.Format(
                            "A registration already exists for URI: \"{0}\" (WCF Service is already open in some IChannelListener).",
                            item.Address));
                }
                catch (Exception ex)
                {
                    if (ex is System.ServiceModel.CommunicationObjectFaultedException ||
                        ex is System.ServiceModel.EndpointNotFoundException)
                    {
                        Debug.WriteLine(ex.DumpObject());
                    }
                    else
                    {
                        throw;
                    }
                }
                finally
                {
                    new Action(client.Dispose).InvokeSafe();
                }
            }
            finally
            {
                new Action(service.Close).InvokeSafe();
            }
        }
    }

(遗憾的是,此代码中的扩展方法,InvokeSafe只是一个try / catch来执行ActionHasElements只是测试一个集合是否为null和empty。

答案 3 :(得分:0)

如果您使用ChannelFactory.CreateChannel,它将返回一个实现服务接口的代理,而无需打开通信通道。但是,代理还实现了IClientChannel,您可以使用它来检查端点是否启动。就我而言,我还需要等待端点启动,因此我使用了一个带有超时的循环:

public static Interface CreateOpenChannel<Interface>(Binding protocol, EndpointAddress address, int timeoutMs = 5000)
{
    for (int startTime = Environment.TickCount;;) {
        // a proxy is unusable after comm failure ("faulted" state), so create it within the loop
        Interface proxy = ChannelFactory<Interface>.CreateChannel(protocol, address);
        try {
            ((IClientChannel) proxy).Open();
            return proxy;
        } catch (CommunicationException ex) {
            if (unchecked(Environment.TickCount - startTime) >= timeoutMs)
                throw;
            Thread.Sleep(Math.Min(1000, timeoutMs / 4));
        }
    }
}

已通过NetNamedPipeBinding测试过。我不确定这是否会与其他绑定相同,或者Open()是否只是打开连接还是测试连接的有效性(例如主机接口是否与客户端接口匹配)。