起動時に管理データを読み込むアプリケーション(.NET 4.0)があります。 25個の同時非同期WCF呼び出しを実行する必要があります。そのうちのいくつかは高速(40ms)で、他の一部は実行に長時間かかります(最大882ms)。データをローカルに保存する予定ですが、最初のアプリケーションの起動時にはできるだけ早く実行する必要があります。タスクを使用して並行非同期WCF呼び出しをオーケストします。
プロキシは.NET 3.5をターゲットとしたライブラリにあり、BeginXxxとEndXxxメソッドのパターンは、Jeffrey RichterのAsync Enumeratorの助けを借りて非同期メソッドにラップされています。
使用される各クライアントプロキシのWCFチャネルファクトリは、呼び出しを開始する前に開かれています。
現在、私はTask.Factory.StartNewを使用して、それぞれの非同期呼び出しを起動するアクションを実行しています。経験は以下のとおりです。
- すべてのBeginXXXコールが送信されます。
- プログラムが少なくとも10秒間自分のコードの外で動作しているようです。
- 最後に、すべてのEndXXXコールが送信され、結果が取得されます。
なぜこのような遅延が発生するのでしょうか。私のコンピュータは4つのコアを持っています。同時通話の数が4に制限されている場合、遅延は全くありません。別の通話を追加するとすぐに遅延が発生します。
助けてください。
EDIT 1:使用されるバインディングは、netTcpBindingです。
Server構成は以下の通りです:
<netTcpBinding>
<binding transactionFlow="true" listenBacklog="500" maxReceivedMessageSize="400000"
portSharingEnabled="false">
<readerQuotas maxDepth="200" />
<reliableSession enabled="false" />
<security mode="None">
<transport clientCredentialType="None" protectionLevel="None" />
<message clientCredentialType="None" />
</security>
</binding>
</netTcpBinding>
<service name="AdminService">
<endpoint address="" binding="netTcpBinding" bindingConfiguration=""
contract="IAdmin">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
</service>
EDIT 2:次の4つのコアのマシン上でWCF 4.5ランタイムによって設定されたデフォルトの調整値です。
ListenBacklog is [500]
MaxConnections is [48]
MaxConcurrentCalls is [64]
MaxConcurrentInstances is [2147483647]
MaxConcurrentSessions is [400]
EDIT 3:ここJ.RichterのAsyncEnumeratorを使用してコードです:
private IEnumerator<int> DoWorkGetXXXX(AsyncEnumerator<MyResult> ae)
{
ae.ThrowOnMissingDiscardGroup(true);
IClientChannel proxy = (IClientChannel)CreateChannel(_bindingName);
bool success = false;
try
{
proxy.Open();
// The call to BeginXXX goes here
((IAcaccount)proxy).BeginGetXXX(..., ae.EndVoid(0, DiscardGetXXX), proxy);
//
yield return 1;
if (ae.IsCanceled())
{
goto Complete;
}
// Iterator was not canceled, process should continue.
// The call to EndXXX goes here
IAsyncResult ar = ae.DequeueAsyncResult();
try
{
ae.Result = ((IAcaccount)ar.AsyncState).EndGetXXX(ar);
proxy.Close();
success = true;
}
// In the mean time, we catch and rethrow :)
// If this exception occurs, we should retry a call to the service
catch (FaultException<AppFabricCachingException> retry)
{
}
// fatal Exception in data service, administrator action required...
catch (FaultException<EFExecutionException> fatal)
{
}
catch (FaultException<EFUpdateException> fatal)
{
}
catch (FaultException<EFNoRowException> nr)
{
}
catch (FaultException fe)
{
}
catch (ServiceActivationException sae)
{
}
catch (CommunicationException ce)
{
}
//
}
finally
{
// If an error occurred, abort the proxy.
if (!success)
{
proxy.Abort();
}
}
// End of operations.
Complete:
proxy = null;
}
これは役に立つかもしれません、それは接続の問題かもしれませんhttp://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/1f863f20-09f9-49a5-8eee-17a89b591007 – codingadventures
あなたの拘束力は何ですか?サーバー構成ですか?サーバー設定を投稿できますか? – evgenyl
@JohnField私は自分の質問を編集した、私はnetTcpBindingを使用しています。 –