0

そこで、(nettcpbinding を介して) WCF サービスを呼び出すコンソール アプリを作成しています。ビジネスでは、タイムアウト値として使用する値を指定できるようにしたいと考えています。私は最初に操作のタイムアウトを試みましたが、それは無視されたようだったので、他の値をたくさん試しました。それらの作品の1つ(または組み合わせ):)

タイムアウトした場合でもチャネルを閉じることができることを望んでいましたが、最後にブロックを閉じると、タイムアウトするまでさらに1分間待機します(タイムアウト値を秒単位で設定しています)。サーバー側のコードに遅延を追加してテストしています-しばらく時間がかかることをシミュレートします。

クローズを最初の try ブロックに移動できますが、チャネルを開いたままにしておくのではないかと心配しています。その後、タイムアウト エラーがユーザーにすばやく報告されます。または、スレッド化を実装する必要がありますか?

public static String ExecuteSearch(List<KeyValuePair<string, string>> paramItems)
{
    var context = GetAdminContext();
    var parsedParameters = ParseParameters((paramItems));

    //TODO: Figure out how to implement timeout - & workout if port number will be passed in?? 
    IPartyProfile partyProfile = null;

    long start = System.Environment.TickCount;

    using (ChannelFactory<IPartyController> factory = new ChannelFactory<IPartyController>("IPartyControllerEndpoint"))
    {
        EndpointAddress address = new EndpointAddress(String.Format("net.tcp://{0}/ServiceInterface/PartyController.svc", parsedParameters.HostName));
        IPartyController proxy = factory.CreateChannel(address);

        if (proxy != null)
        {
            var timeoutTimeSpan = new TimeSpan(0, 0, parsedParameters.TimeOut);
            ((IContextChannel)proxy).OperationTimeout = timeoutTimeSpan;
            factory.Endpoint.Binding.SendTimeout = timeoutTimeSpan;
            factory.Endpoint.Binding.ReceiveTimeout = timeoutTimeSpan;
            factory.Endpoint.Binding.OpenTimeout = timeoutTimeSpan;
            factory.Endpoint.Binding.CloseTimeout = timeoutTimeSpan;

            try
            {
                // TODO: potentially call something more complex
                partyProfile = proxy.GetLatestPartyProfile(context, parsedParameters.PartyId);

            }
            catch (EndpointNotFoundException ex)
            {
                throw new Exception(STATUS_UNKNOWN + ": Endpoint specified not responding", ex);
            }
            catch (TimeoutException ex)
            {
                throw new Exception(STATUS_UNKNOWN + ": Timeout exceeded", ex);
            }
            finally
            {
                try
                {
                    ((IClientChannel)proxy).Close();
                }
                catch (Exception)
                {
                }

            }
        }
    }

    long stop = System.Environment.TickCount;
    long elapsed = (stop - start) / 1000; // in seconds

    return SetResultMessage(elapsed, partyProfile, parsedParameters);
}

編集 - factory.Abort() を使用して、より迅速に終了できると思います。(上記のコードの Close の場所に配置します)。

4

1 に答える 1

1

あなたの説明から、SendTimeout正確に微調整したい値です(さまざまなタイムアウトに関するこの質問も参照してください)。デフォルトでは 1 分ですが、それよりも短い時間 (たとえば 5 秒) に変更すると、proxy.GetLatestPartyProfile実際には 5 秒後に TimeoutException がスローされるはずです (サービス呼び出しが応答するのにそれ以上かかると仮定します)。

現在投稿されているコードでは、問題を引き起こしている可能性のあることが少なくとも 1 つあります。プロキシを作成した後で、ファクトリにタイムアウト値を設定しています。関連するステートメントを並べ替えて、再試行してください。このようなもの:

using (ChannelFactory<IPartyController> factory = new ChannelFactory<IPartyController>("IPartyControllerEndpoint"))
{
    var timeoutTimeSpan = new TimeSpan(0, 0, parsedParameters.TimeOut);
    factory.Endpoint.Binding.SendTimeout = timeoutTimeSpan;

    EndpointAddress address = new EndpointAddress(String.Format("net.tcp://{0}/ServiceInterface/PartyController.svc", parsedParameters.HostName));
    IPartyController proxy = factory.CreateChannel(address);

    if (proxy != null)
    {
        try
        {
            // TODO: potentially call something more complex
            partyProfile = proxy.GetLatestPartyProfile(context, parsedParameters.PartyId);
        }
        // etc.

注:あなたの現在のオーバーロード voorCreateChannelがバインディングに何を使用しているかは完全にはわかりません。以前に設定したバインドを使用することはもっともらしいようですが、それでも問題が解決しない場合は、CreateChannel(Binding, EndpointAddress)オーバーロードを使用して実験することができます。

于 2012-09-14T08:53:34.407 に答える