2009-06-12 15 views
8

Ho un servizio WCF che a volte deve restituire un errore. Per qualche motivo, le chiamate al mio servizio iniziano a timeout con il seguente errore: "Timeout del canale di richiesta durante l'attesa di una risposta dopo 00: 00: 59.8906201. Aumentare il valore di timeout passato alla chiamata su richiesta o aumentare il valore SendTimeout valore sul Binding. Il tempo assegnato a questa operazione potrebbe essere stato una parte di un timeout più lungo. "Perché il servizio WCF restituisce un errore FaultException, timeout dopo 10 chiamate?

Dopo aver esaminato il problema, è emerso un motivo: quando il servizio ha restituito un errore 10 volte, si avvia il timeout. Così ho creato un TestService realizzato da:

public string GetData(int value) 
{ 
    throw new FaultException("A testerror occured"); 
} 

E un TestClient:

protected void RunTestGetData() 
    { 
     using (TestServiceReference.Service1Client client 
      = new WSPerformanceTester.TestServiceReference.Service1Client()) 
     { 
      try 
      { 
       client.GetData(1); 
       client.Close(); 
       outputWriter.WriteLine(string.Format("Call run in thread {0}: GetData()", Thread.CurrentThread.ManagedThreadId)); 
       outputWriter.Flush(); 
      } 
      catch (Exception e) 
      { 
       client.Abort(); 
       client.Close(); 
       outputWriter.WriteLine(string.Format("Error occured in thread {0}: GetData(): {1}", Thread.CurrentThread.ManagedThreadId, e.Message)); 
       outputWriter.Flush(); 
      } 
     } 
    } 

Questo accade solo, quando il servizio sta tornando un FaultException. Se lancio una normale eccezione, il servizio è in grado di continuare a correre dopo la decima chiamata. Ovviamente, mi piacerebbe racchiudere le mie eccezioni in modo piacevole, quindi non è una vera opzione lanciare normali eccezioni.

Perché si verificano queste eccezioni di timeout? Grazie in anticipo per qualsiasi aiuto ..

risposta

1

A quanto pare, il codice del client dovrebbe essere la seguente:

protected void RunTestGetData() 
{ 
    TestServiceReference.Service1Client client 
     = new WSPerformanceTester.TestServiceReference.Service1Client() 
    try 
    { 
     client.GetData(1); 
    } 
    catch (FaultException e) 
    { 
     //Handle fault 
    } 
    try 
    { 
     if (client.State != System.ServiceModel.CommunicationState.Faulted) 
     { 
      client.Close(); 
     } 
    } 
    catch(Exception e) 
    { 
     outputWriter.WriteLine("Error occured in Client.Close()"); 
     outputWriter.Flush(); 
     client.Abort(); 
    } 
} 

Calling client.Abort() dovrebbe essere sempre l'ultima risorsa.

+2

[citazione necessaria] – piers7

1

Potrei sbagliarmi qui, ma penso che abbia qualcosa a che fare con l'hosting del servizio WCF.

Perché potrebbe non essere in grado di rispondere alla richiesta in modo tempestivo.

IIS su Windows XP, ad esempio, può rispondere a 5 richieste simultanee (e non ne sono tanto sicuro al momento). Se vengono fatte più richieste, va in coda.

E credo che potrebbe perdere le richieste e, così facendo, non elaborarle, poiché il test in realtà non fa altro che generare un'eccezione.

2

Penso che ciò potrebbe essere dovuto al fatto che il comportamento predefinito di un servizio WCF è di 10 sessioni simultanee. Stai mantenendo le connessioni aperte dopo che si sono verificate le FaultException? Puoi provare a modificare questo valore in BehaviorConfiguration (ServiceThrottling> MaxConcurrentSessions) e vedere se questo cambia qualcosa. Ti suggerisco di utilizzare l'editor di configurazione del servizio Microsof per verificare quali altri valori sono impostati per impostazione predefinita. (MSDN)

speranza che questo aiuta ...

+0

Ma non dovrebbe il client.Abort() o client.Close() chiude la sessione? E perché questo accade solo quando si usa FaultException? –

+0

Ho la stessa domanda di Jesper. Chiunque? –

+1

Vedere la risposta di @ Jarrod268 per una spiegazione ... grazie! – RoelF

0

Prova il mio client API servizio WCF per modello e vedere se si verificano gli stessi risultati. Sono che qualcosa non è giusto nel codice client ...

The Code

The PPT

Inoltre, abilitare la registrazione dettagliata WCF sia sul client e server ...

3

I don' t avere abbastanza punti per commentare, quindi nuova risposta ...

I servizi in hosting consentono solo un massimo di 10 connessioni simultanee, indipendentemente dal trasporto. Se stai eseguendo servizi WCF all'interno di IIS/WAS non dovresti preoccuparti di questo (a meno che tu non sia su XP/Vista dove sono anche 10 le connessioni simultanee).

Le differenze tra un'eccezione di errore e un'eccezione normale in questo scenario possono tenere conto del risultato visualizzato.

Ricordare che un'eccezione non gestita normale guasta il canale. In tal modo presumo che questo apre una connessione disponibile. Quando si restituisce un errore, esso vince automaticamente il guasto del canale perché consente di fare qualcosa con la connessione e gestire l'errore sul proprio terminale perché è un possibile errore "atteso" mentre un'eccezione non gestita non lo sarebbe.

Anche se si restituisce un errore, è comunque necessario interrompere() la connessione. Inoltre, al di sotto ci sono risorse non gestite quindi assicurati di implementare IDisposable sui chiamanti dei tuoi client/proxy.

2

Mi trovavo di fronte allo stesso problema. Uno sguardo più attento ha rivelato che non stavo chiudendo il client webservice dopo che avevo finito di effettuare le chiamate al webservice. Una volta fatto ciò, non ha fallito nemmeno dopo 10 chiamate di metodo al webservice. Vedi l'esempio qui sotto.

WebServiceClient svcClient = new WebServiceClient(); 

string returnValue = svcClient.GetDocumentName(fileId); 

svcClient.Close(); 

corretto modello:

using(WebServiceClient svcClient = new WebServiceClient()) 
{ 
    return svcClient.GetDocumentName(fileId); 
} 

ClientBase implementa IDisposable, che chiama Close() all'interno del metodo Dispose.

+3

Non è consigliabile includere i comandi WCF nei client WCF. Vedere il seguente articolo: http://msdn.microsoft.com/en-us/library/aa355056.aspx –

+0

grazie anche a questo problema, è stato abbastanza difficile rintracciare il problema. comunque grazie per la pubblicazione – zulucoda