2013-05-07 16 views
5

Ho un'applicazione (.NET 4.0) che carica i dati amministrativi all'avvio. Devo fare 25 chiamate WCF asincrone simultanee, alcune sono veloci (40 ms), altre richiedono più tempo per l'esecuzione, fino a 882 ms. Ho intenzione di archiviare i dati localmente, ma per il primo avvio dell'applicazione, deve essere eseguito il più rapidamente possibile.25 chiamate simultanee asincrone WCF per l'orchestrazione mediante Task

Si noti che i proxy si trovano in una libreria che utilizza .NET 3.5 e utilizzano internamente i metodi BeginXxx e EndXxx con un metodo asincrono con l'aiuto di Async Enumerator di Jeffrey Richter.

Le factory di canali WCF per ogni proxy client che verrà utilizzato vengono aperte prima dell'avvio delle chiamate.

In questo momento, sto utilizzando Task.Factory.StartNew con un'azione che avvia ciascuna chiamata asincrona. L'esperienza è la seguente:

  1. Tutte le chiamate BeginXXX vengono tutte inviate.
  2. Il programma sembra funzionare al di fuori del mio codice per almeno 10 secondi.
  3. Infine tutte le chiamate EndXXX vengono inviate per recuperare i risultati.

Mi chiedo perché si verifichi un tale ritardo. Il mio computer ha 4 core, se il numero di chiamate simultanee è limitato a 4, non c'è alcun ritardo, non appena aggiungo un'altra chiamata, si verifica un ritardo.

Qualsiasi aiuto apprezzato.

MODIFICA 1: Il collegamento utilizzato è netTcpBinding. configurazione

Server segue:

 <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: seguito sono riportati i valori di limitazione predefiniti impostati dal WCF 4.5 runtime su una macchina 4 core.

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

EDIT 3: Ecco il codice usando AsyncEnumerator di J.Richter:

 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

questo potrebbe aiutare, potrebbe essere un problema di connessione http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/1f863f20-09f9-49a5-8eee-17a89b591007 – codingadventures

+0

Qual è il tuo legame? Configurazione del server? Puoi postare la configurazione del server? – evgenyl

+0

@JohnField Ho modificato la mia domanda, sto usando netTcpBinding. –

risposta

0

Si potrebbe provare a giocare con il valore di serviceThrottling, così come maxItemsInObjectGraph, MaxBufferSize, MaxBufferPoolSize (i averli impostati su int.MaxValue).

Problemi correlati