Ho un'app client/server WCF che comunica tramite HTTP utilizzando WSHttpBinding.WCF Richieste simultanee di accumulo sul server quando si utilizza WSHttpBinding
Impostazione server: self-hosting, utilizzando lo standard WCF ServiceHost
. La mia classe servizio attuale viene attribuito come:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.PerSession,
UseSynchronizationContext = false)]
Client Setup: (. proxy.call_server_method
blocchi, fino al momento in cui il server ha risposto in pieno) usando un proxy client generato visual-studio utilizzando chiamate di servizio sincrone
Scenario: Ho una chiamata di metodo particolare che richiede 20 secondi per l'esecuzione sul server. Il client chiama questo metodo in un thread separato, quindi non viene trattenuto e lo ConcurrencyMode.Multiple
significa che WCF deve eseguirlo anche in un thread separato sul server.
Questa teoria è supportata dal fatto che quando configuro la mia app per utilizzare NetTcpBinding
, tutto funziona correttamente.
Problema:
Se devo configurare l'applicazione per utilizzare WSHttpBinding
, allora questo metodo di chiamata a lunga fa sì che le richieste HTTP a 'back up'. Ho verificato questo comportamento sia dall'ispezione dei miei registri, sia dal debug delle richieste HTTP usando il violinista.
Esempio:
- client avvia 20-seconda richiesta a lungo su un thread in background
- client avvia richiesta B e C sul thread in primo piano
- Richieste B e C ottenere inviato al server, che doesn 't loro trattamento fino a quando non è fatto con il 20-seconda richiesta lungo
Ma a volte:
- Le richieste B e C non vengono inviate (non appaiono nemmeno nel violinista) finché non viene restituita la richiesta di 20 secondi (questo è raro).
- Nota: l'impostazione
<add address="*" maxconnection="100"/>
nell'app.config del client ha impedito l'esecuzione di questo (sembra).
- Nota: l'impostazione
- Richiesta B viene inviato e riceve subito una risposta, mentre la richiesta di C è trattenuto fino a quando il 20-seconda completa (questo è raro)
Ecco una cronologia dal violinista dimostrare il problema: (clicca per la versione più grande)
Come si può vedere, le richieste sono tutti sempre eseguito il backup sul server. Una volta che la richiesta di 20 secondi è stata completata, le risposte vengono tutte inondate, ma si noti che ci sono alcune richieste che non rappresentano in attesa ...
Quindi, Domande:
- Che diamine sta succedendo qui? Perché funziona correttamente utilizzando
NetTcpBinding
e non funziona utilizzandoWSHttpBinding
? - Perché il comportamento incoerente?
- Cosa posso fare per risolverlo?
Note:
- Non è bloccaggio sul server. Ho impostato i punti di interruzione e utilizzato
!syncblk
e segnala costantemente che non vengono bloccati blocchi. - non è il mio threading (NetTcpBinding dovrebbe non funzionare in altro modo)
- ho
<serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" />
set nel app.config del server - Il 20-seconda chiamata è solo in attesa su un timer, non è thrashing la CPU o del disco o rete
- Preferirei una soluzione che non prevedesse la re-architettura dell'applicazione per l'utilizzo di chiamate asincrone ... è un grosso gruppo di codice legacy e non voglio davvero fare scherzi con cose che non faccio t capire.
+1 Eccellente il layout della questione. –
Hai mai risolto questo problema? Se sì, come lo hai risolto? – DivisionByZorro
Aggiunto un auto-risposta che descrive la nostra "soluzione" finale –