0

私のアプリケーションでは、実行可能ファイルを手動で開始する必要があります。この実行可能ファイルはサーバーとして機能し、WCF サービスを開始しますが、初期化プロセス全体に時間がかかります。私のクライアント(新しいプロセスを作成したもの)では、 WCF サービスASAPを使用する必要があります。

そのため、サービスの Ping() メソッドを呼び出して、サービスが開始されたことを 100 ミリ秒ごとに確認します。最初の呼び出しは、私が処理する EndPointNotFoundException をスローします。しかし、2 番目の呼び出しは CommunicationObjectFaultedException をスローします。確認したところ、EndPointNotFoundException を処理した後、クライアント プロキシの作成に使用する CommunicationObject の状態は Opened です。私のアプローチは間違っていますか?サービスが開始されているかどうかを確認するにはどうすればよいですか?

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 を指定する場合、サービスがオンラインまたはオフラインになると、サービスはアナウンス メッセージを自動的に送信します。自分でアナウンス メッセージを明示的に送信する場合は、このクラスを使用します。

探しているサポートを提供するメソッドは次のとおりです。サービスの状態についてクライアントにメッセージを送信するために使用できますAnnounceOnlineAnnounceOfflineこれにより、ループ内の ping の必要性を取り除く準備ができたときに、クライアントがサービスから通知を受けることができます。

于 2013-05-14T14:30:15.893 に答える