1

async/await パターンを使用して大量の呼び出しを行う .NET 4.5 WCF クライアント アプリがあります。私の開発マシンは 8 GB RAM のデュアル プロセッサです (Amazon AWS では 8 GB RAM の 5 CPU で運用されます)。コードによって呼び出されるリモート WCF サービスは、必要な Web メソッドで out および ref パラメーターを使用します。私のコードは毎回プロキシ クライアントをインスタンス化し、すべての結果を public ConcurrentDictionary に書き込み、null を返します。

Perfmon を実行してシステムのスレッド数を監視したところ、28 ~ 30 になりました。私のクライアントが行われた通話の量を完了するのに何時間もかかります. はい、何時間も。リモート サービスは大企業によって支えられており、WCF 呼び出しを受信するためのサーバーが多数あるため、より多くの呼び出しを投げることができれば、より良い結果が得られます。

プロキシメソッドは「await」を持つことができないため、WCF呼び出しを行うメソッドが「async」で装飾されていても、実際にはまだ同期的に起こっていると思います。本当?

私のコードは次のようになります。

   async private void CallMe()
    {
    Console.WriteLine( DateTime.Now );
    var workTasks = this.AnotherConcurrentDict.Select( oneB => GetData( etcetcetc ).Cast<Task>().ToList();
    await Task.WhenAll( workTasks );
    }


    private async Task<WorkingBits> GetData(etcetcetc)
    {
    var commClient = new RemoteClient();
    var cpResponse = new GetPackage();
    var responseInfo = commClient.GetData( name, password , ref (cpResponse.aproperty), filterid , out cpResponse.Identifiers);
    foreach (var onething in cpResponse.Identifiers)
    { 
        // add to the ConcurrentDictionary
    }
    return null; // I already wrote to the ConcurrentDictionary so no need to return anything

WCF 呼び出しに ref および out パラメータがあるため、responseInfo は待機できません。

これを高速化する方法は、このメソッドに async/await を配置するのではなく、await/async を作成できるラッパー メソッドを作成することだと考えていましたが、それが最もスマートで安全な方法ではありません。

サービスへのアウトバウンド呼び出しを増やすスマートな方法は何ですか (IO 完了スレッド プールを拡張し、呼び出しをバックグラウンドで実行して、Task.WhenAll をより迅速に完了できるようにします)。

すべてのアイデア/サンプル/ポインターに感謝します。どこかでボトルネックにぶつかっています。

4

1 に答える 1

4

1)呼び出しをブロックするだけでなく、実際に非同期で呼び出していることを確認してください。ここではコード サンプルが役立ちます。
2)これを行う必要がある場合があります:

ServicePointManager.DefaultConnectionLimit = 100;

デフォルトでは、同じサーバーへの同時接続は 2 つだけ許可されます。
3) 呼び出しが完了したら、必ずプロキシ オブジェクトを破棄して、リソースを占有しないようにします。

非同期で処理している場合、スレッドプールのサイズがボトルネックになることはありません。発生している問題の種類をよりよく理解するために、 および を使用Interlocked.IncrementInterlocked.Decrementて、保留中の呼び出しの数を追跡し、それがどこかで制限されているかどうかを確認できます。

実際の呼び出しを、ボトルネックがないとわかっている非常に単純なメソッドの呼び出しに置き換えて、問題がクライアントにあるのかサーバーにあるのかを確認することもできます。

于 2012-12-04T16:48:57.717 に答える