2013-05-07 8 views
5

Ich habe eine Anwendung (.NET 4.0), die beim Start administrative Daten lädt. Ich muss 25 gleichzeitige asynchrone WCF-Anrufe machen, einige von ihnen sind schnell (40ms), andere dauern länger bis zu 882 ms. Ich plane, die Daten lokal zu speichern, aber für den allerersten Anwendungsstart muss es so schnell wie möglich erledigt werden.25 gleichzeitige asynchrone WCF-Aufrufe zur Orchestrierung mit Tasks

Es sollte angemerkt werden, dass die Proxys in einer Bibliothek sind, die auf .NET 3.5 abzielt und intern das BeginXxx- und EndXxx-Methodenmuster verwendet, das mit Hilfe von Jeffrey Richters Async Enumerator in eine asynchrone Methode eingebunden wird.

Die WCF-Kanalfactorys für jeden Clientproxy, der verwendet wird, werden vor dem Start der Aufrufe geöffnet.

Zu diesem Zeitpunkt verwende ich Task.Factory.StartNew mit einer Aktion, die jeden Async-Aufruf startet. Die Erfahrung ist folgende:

  1. Alle BeginXXX Anrufe werden alle gesendet.
  2. Das Programm scheint für mindestens 10 Sekunden außerhalb meines Codes zu arbeiten.
  3. Schließlich werden alle EndXXX-Aufrufe gesendet, um die Ergebnisse zu erhalten.

Ich frage mich, warum eine solche Verzögerung auftritt. Mein Computer hat 4 Kern, Wenn die Anzahl der gleichzeitigen Anrufe auf 4 begrenzt ist, gibt es keine Verzögerung überhaupt, sobald ich einen weiteren Anruf hinzufüge, wird eine Verzögerung erfahren.

Jede Hilfe wird geschätzt.

EDIT 1: Die verwendete Bindung ist netTcpBinding.

Server-Konfiguration folgt:

 <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: Im Folgenden sind die Standardwerte eingestellt Drosselung durch die WCF 4,5-Laufzeit auf einer 4-Core-Maschine.

ListenBacklog is [500] 
MaxConnections is [48] 
MaxConcurrentCalls is [64] 
MaxConcurrentInstances is [2147483647] 
MaxConcurrentSessions is [400] 

EDIT 3: Hier ist der Code J.Richter des AsyncEnumerator mit:

 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; 
     } 
+0

dies könnte helfen, könnte es ein Verbindungsproblem sein http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/1f863f20-09f9-49a5-8eee-17a89b591007 – codingadventures

+0

Was ist Ihre Bindung? Serverkonfiguration? Können Sie die Serverkonfiguration posten? – evgenyl

+0

@JohnField Ich habe meine Frage bearbeitet, ich benutze netTcpBinding. –

Antwort

0

Sie könnten versuchen, mit dem Wert von serviceThrottling sowie MaxItemsInObjectGraph, MaxBufferSize, MaxBufferPoolSize (i zu spielen habe sie auf int.MaxValue gesetzt).

Verwandte Themen