Domanda

Ho un servizio WCF e un'applicazione con un servizio di riferimento ad esso, e con l'applicazione ho un ciclo e in ogni iterazione si sta facendo una chiamata a un metodo in questo WCF web-service.

Il problema è che dopo circa 9 chiamate o giù di lì, si ferma solo ... e se premete il pulsante Pause di VS, vedrete che si è bloccato sulla riga in cui si effettua la chiamata.

Dopo qualche tempo in attesa di essa, questo TimeoutException è gettato:

  

Il canale richiesta è scaduta, mentre   in attesa di una risposta dopo   00: 00: 59,9970 mila. Aumentare il timeout   valore passato alla chiamata per richiedere o   aumentare il valore SendTimeout sulla   Rilegatura. Il tempo assegnato a questa   operazione può essere una porzione di un   più timeout.


Ho fatto delle ricerche un po 'su questo, e ho trovato alcune soluzioni che hanno coinvolto la modifica del app.config nella domanda, e qui sono alcuni estratti di esso:

<serviceBehaviors>
    <behavior name="ThrottlingIssue">
        <serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500" />
    </behavior>
</serviceBehaviors>

.

<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" 
 maxArrayLength="2147483647" 
 maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> 

Poi, dopo mi fermo il debug, dopo un paio di minuti, un messaggio di errore compare mi dice che si è verificato un Errore grave .

Come posso risolvere questo problema? Non ho avuto questo problema quando stavo lavorando con un normale servizio Web.


Per avere un riferimento, qui è tutta la app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="ThrottlingIssue">
                    <serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IDBInteractionGateway" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
                        maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" establishSecurityContext="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:28918/DBInteractionGateway.svc"
                binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IDBInteractionGateway"
                contract="DBInteraction.IDBInteractionGateway" name="WSHttpBinding_IDBInteractionGateway">
                <identity>
                    <dns value="localhost" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

[Aggiornamento] Soluzione:

A quanto pare, dopo ogni richiesta si deve Close il collegamento ... Ora sto chiudendo la connessione dopo ogni richiesta e che sta funzionando come un fascino.

Anche se quello che io ancora non riesco a capire è che nel mio app.config, ho impostato il mio maxConcurrentCalls e MaxConcurrentSessions a 500, e tuttavia, posso solo fare 10. Qualcuno ha una risposta per quello ? (Forse ho qualcosa che non va nel mio app.config postato sopra)

La risposta per la domanda di cui sopra (ora tratteggiata) è perché ero la modifica del app.config cliente, non il file di configurazione del servizio (web.config)

È stato utile?

Soluzione

Il numero predefinito di connessioni simultanee consentito è 10.
Molto probabilmente il client non sta chiudendo i collegamenti.

Per aumentare il numero di chiamate contemporanee, si dovrà aggiungere il vostro comportamento per la configurazione del servizio, non il cliente.

Altri suggerimenti

Una chiamata a clientservice.close () risolverà il problema.

Mi sono imbattuto in questo problema questa settimana e non ero in grado di capire tutto ciò che stava succedendo. Realtà ho fatto cambiare la mia chiamata al mio servizio alla Dispose() il client del servizio, ma non sembrava avere alcun effetto. A quanto pare, ci fu un altro chiamata di servizio in agguato da qualche parte.

Che cosa può essere interessante da notare è quello che mi ha fatto decidere che questo è stato non il problema: questo limite non è legato al numero effettivo di connessioni socket per il webservice. Quando si colpisce il limite maxConcurrentSessions, c'è ancora solo una connessione socket reale . Stavo controllando questo con netstat, che mi ha portato alla conclusione sbagliata. Così, non confondere le sessioni con i socket .

Abbiamo interfacce definite per tutti i nostri servizi WCF, quindi ho intenzione di adattare questo modello nel mio codice ora:

IMyService service = new MyServiceClient();
using (service as IDisposable)
{
    service.MyServiceMethod();
}

Che è anche interessante, è che il problema non si è verificato per me quando i servizi (e sito web) sono stati ospitati su IIS. La configurazione è (quasi) identici, eppure non poteva riprodurre questo comportamento su quella macchina. Direi che è una buona cosa:)

@ John Saunders (circa assegnazione variabile using):

Di solito faccio mettere l'assegnazione variabile nell'istruzione using. Ma l'IMyService che ha generato non è implicitamente convertibile in IDisposable. Se si voleva davvero l'assegnazione in là, suppongo che l'alternativa potrebbe essere:

IService service;
using ((service = new ServiceClient()) as IDisposable)
{
}

che lascia ancora il problema della portata variabile di essere sbagliato, però. Il riferimento a IService service è inutilizzabile, ma ancora nell'ambito. Quindi questo sarebbe meglio a questo proposito:

using (IDisposable serviceDisposable = new ServiceClient())
{
     IService service = (IService)serviceDisposable;
}

Questo mi richiede di introdurre un nome di variabile in più però. * Meh *

Questo può essere risolto creando classe singleton come interfaccia tra il riferimento di servizio Web e l'applicazione. Quindi si creerà una sola istanza di riferimento del servizio.

class ServiceInterface
{
     private static ServiceInterface  _instance;
     private ServiceClient _service = new ServiceClient ;
     private ServiceInterface()
     {
       //Prevent accessing default constructor
     }

     public static ServiceInterface GetInstance()
     {

     if(_instance == null)

     {

      _instance = new ServiceInterface();

    }

        return _instance;



 }


   // You can add your functions to access web service here

    Public int PerformTask()
    {
         return _service.PerformTask();
    }
}

configurare l'analisi ed eseguire il ciclo? Può essere che il canale sta diventando colpevolizzata e causando al cliente di time out.

Dopo aver tirato i miei capelli più di un molto problema simile che non è stato risolto da una Close() o Dispose() Vorrei aggiungere una soluzione semplice che ha reso il mio giorno, vale a dire aumentando la ServicePointManager.DefaultConnectionLimit che di default è 2.

  

"La proprietà DefaultConnectionLimit imposta il numero massimo predefinito di connessioni simultanee che l'oggetto ServicePointManager assegna alla proprietà ConnectionLimit nella creazione degli oggetti ServicePoint."

Nel mio caso la mia domanda in contatto con successo al mio servizio remoto 2 volte, al terzo tentativo, semplicemente, non ha cercato di connettersi al servizio. Invece ha aspettato per un po 'prima del timeout con lo stesso messaggio di errore come nella domanda di cui sopra. Aumentando DefaultConnectionLimit risolto questo. Per aggiungere alla frustrazione questo comportamento è stato un po 'casuale -. In un caso su 10 il webservice è stato invocato con successo multipla (> 2) volte

La soluzione origina e vengono ulteriormente discusso questi due fili: wcf-timeout-eccezioni detailed- indagini e WCF-service-throttling . risolto il mio problema.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top