16

クライアントアプリケーションの開始後の最初のWCF呼び出しが、2番目の呼び出しに比べてはるかに時間がかかる理由を理解しようとしています。

それをテストするために私がしたこと:

  1. シンプルなセルフホストのWCFサーバーとコンソールクライアントを実装しました。
  2. サーバーがウォームアップされています-テストを実行する前に、サーバーを実行してメソッドを数回呼び出します。
  3. バインディングはbasicHttpBinding、ネットワークとセキュリティのオーバーヘッドを削減することです。
  4. テストシナリオ-コンソールクライアントアプリを起動し、2つの同一のWCFサービス呼び出しを続けて行います。

私のテストでは、最初の呼び出しで約700ミリ秒、2番目の呼び出しで約3ミリ秒が表示されます。

JITコンパイラにとっては1秒近く時間がかかりすぎるようです。その時間がEntityFrameworkのような複雑なインフラストラクチャの初期化に使用される場合は受け入れますObjectContextが、私のコードは非常に単純で、プロキシクラスはすでにコンパイルされています。

netNamedPipeBindingバインディングも試してみました。結果はパターンを証明します-最初の呼び出しには約800ミリ秒かかり、2番目の呼び出しには約8ミリ秒かかります。

最初のサービスコールに時間がかかる理由を誰かが説明できれば幸いです。

Win764ビットでテスト済み。

私の実装は以下のとおりです。

契約:

[ServiceContract]
public interface ICounter
{
        [OperationContract]
        int Add(int num);
}

サービスの実装:

public class CounterService: ICounter
{
        private int _value = 0;

        public int Add(int num)
        {
            _value += num;
            Console.WriteLine("Method Add called with argument {0}. Method  returned {1}", num, _value);
            return _value;
        }
}

サーバーの実装:

class Program
{
    static void Main(string[] args)
    {
        Uri baseAddress = new Uri("http://localhost:8080/Service");

        // Create the ServiceHost.
        using (ServiceHost host = new ServiceHost(typeof(CounterService), baseAddress))
        {
            host.Open();

            Console.WriteLine("The service is ready at {0}", baseAddress);
            Console.WriteLine("Press <Enter> to stop the service.");
            Console.ReadLine();

            // Close the ServiceHost.
            host.Close();
        }
    }
}

サーバー構成:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="Server.CounterService">
        <endpoint address="base" binding="basicHttpBinding" name="baseDefault"
          contract="Contract.ICounter" />
        <endpoint address="net.pipe://localhost/Service/netNamedPipe"
          binding="netNamedPipeBinding" name="netNamedPipeDefault" contract="Contract.ICounter" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

クライアントの実装(CounterProxyサービス参照から生成されます):

Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();

using (var proxy = new CounterProxy.CounterClient(_endpointConfigurationName))
{
    output = proxy.Add(1);
}

stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;

2回続けて呼び出されたコードを含む関数。

クライアント構成:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <client>
      <endpoint address="http://localhost:8080/Service/base" binding="basicHttpBinding"
          contract="CounterProxy.ICounter"
          name="baseDefault" />
    </client>
  </system.serviceModel>
</configuration>
4

4 に答える 4

8

通常、最初の呼び出しには時間がかかります。その呼び出しでは、Channel Factoryがインスタンス化され、通信の準備が整うため、時間がかかるためです。作成されたChannel Factoryものはキャッシュされ、後続の呼び出しで再利用されるため、時間が短縮されます。

http://social.msdn.microsoft.com/Forums/en/wcf/thread/43f89088-546b-46b0-adf8-214deb1741bd

于 2012-06-02T05:03:19.550 に答える
3

WCF サービスへの呼び出しが 15 秒未満の頻度で行われている場合 (アプリケーションで約 20 秒待機する必要があることがわかりました)、次の Microsoft ブログで問題が説明されているようです: http://blogs.msdn.com/b/wenlong /archive/2010/02/11/why-does-wcf-become-slow-after-being-idle-for-15-seconds.aspx

この記事は、 SetMinThreads () の修正について言及しているこのエントリにもリンクしていますが、これも問題の原因となっているようです。 wcf-responses-slow-and-setminthreads-does-not-work.aspx

于 2015-06-15T03:39:23.317 に答える
2

同様の問題があります。実際に行ったことは、一定の間隔で WCF サービスを呼び出すサービスを作成したことです。エレガントなソリューションではないことはわかっていますが、機能しています。

于 2012-06-02T04:43:20.807 に答える
2

サービス プロキシ インスタンスを最初に作成したとき、30 秒程度の遅延が見られましたが、これはある種のネットワーク タイムアウトに関連しているに違いないとわかっていました。

最終的には、ここで強調表示されているように、企業プロキシ (yay Websense) によってブロックまたはフラストレーションが発生していた証明書失効リストのチェックが実際に行われました: WCF サービスの起動が遅すぎますか? CRL チェックを考えたことはありますか? .

今後の参考のために、またリンクが無効になった場合に備えて、クライアント構成に以下を追加することになりました。

<configuration>
  <runtime>
    <generatePublisherEvidence enabled=“false”/>
  </runtime>
</configuration>
于 2016-05-04T09:27:47.743 に答える