0

在我的应用程序中,我必须手动启动一个可执行文件。此可执行文件充当服务器并启动 WCF 服务,但整个初始化过程需要时间。在我的客户端(创建了新进程)中,我必须尽快使用 WCF服务

因此,我通过调用服务的 Ping() 方法每 100 毫秒检查一次服务是否已启动。第一次调用会引发我处理的 EndPointNotFoundException。但第二次调用会引发 CommunicationObjectFaultedException。我已经检查过,在处理 EndPointNotFoundException 后,我用来创建客户端代理的 CommunicationObject 的状态已打开。我的方法是否错误,应该如何检查服务是否启动?

UPDATE1:这就是我启动 WCF 服务的方式:

ServiceHost serviceHost = new ServiceHost(typeof(TestService));
const string address = "net.pipe://localhost/testservice";
Binding binding = new NetNamedPipeBinding();
binding.ReceiveTimeout = TimeSpan.MaxValue;
serviceHost.AddServiceEndpoint(typeof(ITestService), binding, address);

serviceHost.Open();
while (true)
{
    Thread.Sleep(100);
}

UPDATE2:这就是我创建代理的方式:

ChannelFactory<ITestService> channelFactory =
        new ChannelFactory<ITestService>(new NetNamedPipeBinding(), "net.pipe://localhost/testservice");
_testServiceProxy = channelFactory.CreateChannel();

这就是我 ping 服务的方式:

private static bool IsServiceAvailable(ITestService serviceProxy)
{
    const int maxNumberOfTries = 100;
    const int timeout = 100;
    bool isServiceAvailable = false;
    int numberOfTries = 0;

    do
    {
        Thread.Sleep(timeout);
        try
        {
            serviceProxy.Ping();
            isServiceAvailable = true;
        }
        catch (EndpointNotFoundException)
        {}
        numberOfTries++;

        if (numberOfTries > maxNumberOfTries)
            break;
    }
    while (!isServiceAvailable);

    return isServiceAvailable;
}
4

2 回答 2

4

问题是由于您不能重用有故障的代理,您应该创建一个新代理。

private static bool IsServiceAvailable(ChannelFactory<ITestService> channelFactory)
{
    const int maxNumberOfTries = 100;
    const int timeout = 100;
    bool isServiceAvailable = false;
    int numberOfTries = 0;

    do
    {
        Thread.Sleep(timeout);
        try
        {
            using(var proxy = channelFactory.CreateChannel())
                proxy.Ping();

            isServiceAvailable = true;
        }
        catch (EndpointNotFoundException)
        {}
        numberOfTries++;

        if (numberOfTries > maxNumberOfTries)
            break;
    }
    while (!isServiceAvailable);

    return isServiceAvailable;
}
于 2013-05-14T11:24:52.347 回答
3

.NET 框架有一个名为System.ServiceModel.Discovery的命名空间,其中包含一些可能对您的用例有用的类。特别是AnnouncementClient类,它允许服务发布公告消息。从文档中:

公告消息包含有关服务的信息,例如其完全限定的合同名称、服务运行的任何范围以及服务想要发送的任何自定义元数据。

就能够知道服务何时在线而言,这个类有一个机制。从文档中:

如果服务添加了 ServiceDiscoveryBehavior 行为并指定了 AnnouncementEndpoint,则服务会在服务上线或下线时自动发送通知消息。当您想自己显式发送公告消息时,请使用此类。

提供您正在寻找的支持的方法是:AnnounceOnline并且AnnounceOffline您可以使用这些方法向您的客户发送有关您的服务状态的消息。这将允许您的客户端在准备就绪时收到服务的通知,从而无需在循环中执行 ping。

于 2013-05-14T14:30:15.893 回答