2011-07-27 13 views
6

Sto prelevando dati JSON da diversi server remoti contemporaneamente su HTTP, utilizzando un servizio WCF su entrambi gli endpoint client e server. Sto notando che per ogni richiesta successiva che inizia in modo asincrono il tempo richiesto da una richiesta HTTP è in genere crescente, anche se la quantità di dati non aumenta necessariamente. In altre parole, se mi metto 12 thread pool di thread (usando Funz <> .BeginInvoke) allora ogni richiesta, dopo essere stato cronometrato, sta mostrando nei miei ceppi come tale:Scaricamento contemporaneo dei dati JSON dai servizi remoti

:HttpRequest invoked. Elapsed: 325ms 
    :HttpRequest invoked. Elapsed: 27437ms 
    :HttpRequest invoked. Elapsed: 28642ms 
    :HttpRequest invoked. Elapsed: 28496ms 
    :HttpRequest invoked. Elapsed: 32544ms 
    :HttpRequest invoked. Elapsed: 38073ms 
    :HttpRequest invoked. Elapsed: 41231ms 
    :HttpRequest invoked. Elapsed: 47914ms 
    :HttpRequest invoked. Elapsed: 45570ms 
    :HttpRequest invoked. Elapsed: 61602ms 
    :HttpRequest invoked. Elapsed: 53567ms 
    :HttpRequest invoked. Elapsed: 79081ms 

il processo è abbastanza semplice. Sto semplicemente iniziando ogni richiesta in un ciclo e poi chiamando .WaitAll() su tutte le operazioni prima di utilizzare i dati consolidati.

Sembra che le richieste Http stiano prendendo più tempo di quanto dovrebbero anche con piccole quantità di dati. In effetti, la differenza tra piccole e grandi quantità di dati appare complessivamente minima. Questo tipo di collo di bottiglia sarebbe dovuto a richieste HTTP simultanee che dovevano condividere larghezza di banda, oppure esiste un problema di threading/cambio di contesto qui? Sto solo cercando di essere indicato nella giusta direzione.

EDIT - Solo per chiarezza, ho corso lo stesso processo sincrono ed ecco i risultati:

:HttpRequest invoked. Elapsed: 20627ms 
    :HttpRequest invoked. Elapsed: 16288ms 
    :HttpRequest invoked. Elapsed: 2273ms 
    :HttpRequest invoked. Elapsed: 4578ms 
    :HttpRequest invoked. Elapsed: 1920ms 
    :HttpRequest invoked. Elapsed: 564ms 
    :HttpRequest invoked. Elapsed: 1210ms 
    :HttpRequest invoked. Elapsed: 274ms 
    :HttpRequest invoked. Elapsed: 145ms 
    :HttpRequest invoked. Elapsed: 21447ms 
    :HttpRequest invoked. Elapsed: 27001ms 
    :HttpRequest invoked. Elapsed: 1957ms 

Il tempo totale (in quanto la sua sincrono) è salito, ma è possibile vedere chiaramente che ogni singola richiesta è generalmente più veloce. Sfortunatamente non conosco alcun modo per isolare il problema, ma la mia ipotesi è che sia un problema di condivisione della larghezza di banda tra i thread.

Così ho qualche domanda più semplice che ho è:

1) Se io uso un filo non di thread, sarebbe questa migliorare

2) Dovrei raggruppare le operazioni in pochi discussioni, piuttosto di ogni richiesta ha il suo?

3) Si tratta di un problema standard quando si tenta di scaricare contemporaneamente dati su Http?

+0

In realtà mi sto occupando anche di un po 'dello stesso problema con più richieste HTTP simultanee. Se invio tutte e 50 le richieste tutte contemporaneamente, il primo ritorna in 300 ms e l'ultimo ritorna dopo 2000 ms. I tuoi risultati sembrano indicare che sta succedendo qualcos'altro. Nel tuo test sincrono, la prima richiesta è tornata dopo gli anni 20 ?! Forse questo è più un problema sul lato server, che tipo di servizio è questa chiamata? –

+0

@Mike Richard, vedi il mio link nella risposta che ho postato, dovrebbe aiutarti. –

risposta

0

La migliore risposta a questa domanda che in ultima analisi, si avvicinò con provenivano da questo link:

http://blogs.msdn.com/b/wenlong/archive/2010/02/11/why-are-wcf-responses-slow-and-setminthreads-does-not-work.aspx

che si applica se si chiama lo stesso metodo servive ripetutamente.

Tramendo ThreadPool.SetMinThreads() su client e server, sono riuscito a ottenere risultati migliori.

Tuttavia ci sono ancora molti problemi di lentezza con WCF e trasferimento su HTTP che non ho davvero ottenuto fino in fondo.

2

Come da domanda this, esiste un'impostazione che controlla quante richieste HTTP simultanee possono essere fatte. Inoltre, dovresti utilizzare il metodo BeginGetResponse su HttpWebRequest per il download simultaneo perché è meno costoso della creazione di thread. Guarda here per esempi.

+0

Grazie. L'impostazione della richiesta HTTP simultanea è intesa per il server o il client o entrambi? Inoltre, attualmente sto utilizzando ChannelFactory per chiamare il servizio WCF, chiamando il metodo in base al nome del contratto di servizio. –

+0

L'impostazione deve essere modificata sull'applicazione che sta eseguendo il download. – eulerfx

+0

Questa impostazione di configurazione si applica solo se ho utilizzato HttpWebRequest o dovrebbe funzionare anche con una chiamata WCF ChannelFactory ? Potrei dover cercare se esiste un'impostazione equivalente per i client Wcf. –

2

Potrebbe essere correlato alla modalità di concorrenza del servizio. Controlla http://msdn.microsoft.com/en-us/library/system.servicemodel.concurrencymode.aspx e assicurati che il servizio non sia a thread singolo.

+0

Questo non sembra essere d'aiuto. Penso che questo sia un problema di threading sul client in realtà, non è sicuro. –

+0

ThreadPool gestirà il numero di thread da solo - non c'è molta garanzia che avrete 12 thread in esecuzione contemporaneamente a meno che non modificiate SetMaxThreads/SetMinThreads. In secondo luogo, analizzerei cosa sta facendo il servizio (lato server) - forse c'è una sorta di contesa della serratura (come l'accesso ai DB/accesso in scrittura allo stesso file, ecc ...) – bkdc

+0

Diresti che questo comportamento è previsto però, dato che sul client, un gruppo di download simultanei dovrà condividere larghezza di banda? Significando che sto colpendo 900kb/s quando faccio un singolo download, potrei perdere velocità per ogni download simultaneo che aggiungo. Se questo è il caso, penserei che c'è poco che posso fare. –

Problemi correlati