2012-06-01 19 views
25

Dopo aver trascorso più tempo di quanto sia ragionevole trovare una risposta a questa semplice domanda, ho pensato di lasciare i miei risultati qui in modo che gli altri non debbano saltare attraverso tutti i cerchi e percorsi sbagliati che L'avevo appena seguitoCome utilizzare correttamente TcpClient ReadTimeout

Il problema è che se si utilizza la proprietà ReadTimeout di TcpClient e l'operazione di lettura è scaduta, Microsoft ha deciso di chiudere il socket. Questo non è previsto, non è auspicabile, non è eseguito da alcuna altra implementazione socket che conosco, e non ha alcuna ragione valida per cui questo dovrebbe essere il caso diverso dalla pigrizia del programmatore. Ma questo è ciò che Microsoft ha scelto di fare.

Ad ogni modo, tutte le soluzioni alternative che ho trovato, incluso in questo sito, hanno avuto vari modi di eseguire una qualche forma di polling occupato e alcuni addirittura hanno iniziato a dare il via a un'altra discussione per eseguire una semplice chiamata di lettura. Mi dispiace, ma ho cose migliori da fare con la mia CPU che sedermi lì e sondaggi occupati, soprattutto con molti socket aperti, quindi questa non è un'opzione per me. Dopotutto, non siamo agli inizi degli anni '90, dove i sondaggi più impegnativi erano come si facevano le cose. Al giorno d'oggi, abbiamo questa cosa chiamata sistemi operativi che si occupano di questi tipi di cose in modo abbastanza efficiente usando gli interrupt.

In ogni modo, su un altro ricerca tangenziale sono incappato in questo vecchio post del blog:

http://blogs.msdn.com/b/mflasko/archive/2006/02/20/535655.aspx

MSDN Blog> Blog di Mike Flasko> Gestione di un timeout durante la lettura dei dati di rete

Le rosticcerie chiave che ti dice la soluzione su come gestire correttamente i timeout di lettura sono:

A questo punto si può essere tentati di catturare l'eccezione e quindi riemettere la lettura sullo stesso NetworkStream. Questa strategia può portare a errori imprevisti. La cosa migliore da fare è ora considerare il NetworkStream (socket) come in uno stato instabile. Questo perché quando lo stack sottostante scade, la lettura I/O sottostante viene annullata. Se i dati arrivano allo stesso tempo, i dati andranno persi, causando un flusso di dati corrotto.

e la soluzione:

Un approccio migliore è quello di intercettare l'eccezione, chiudere la presa o TCPClient e ricollegare se necessario.

Mentre io continuo a pensare che questo mette peso inutile per l'utente delle API, almeno è la soluzione più adeguata sono stato in grado di scoprire le decine di siti ho guardato cercando di capire per fare un Presa semi-corretta ReadTimeout.

Spero che questa domanda/commento salvi a qualcuno le ore che ho impiegato per trovare.

+0

ho lavorato con quella roba ultimamente, se imposto il timeout a 1000 ms e rileviamo l'eccezione, a volte potrei finire per ritardare alcune procedure, perché è piuttosto difficile determinare se la trasmissione è veramente finita OPPURE hai un problema di rete.Per esempio, ho una parte di codice che trasmette un'immagine PNG attraverso la rete, il codice è qualcosa di simile a quando (vero) {prova Ricevi dati e metti in un buffer di 4096 byte interruzioni su eccezione; quindi se nessun dato disponibile, si interrompe mentre; } Se non metto un thread da 1ms in sleep, (so che fa schifo) i dati disponibili torneranno falsi troppo presto e l'immagine si romperà. – Felype

+0

Questa è una domanda? Credo che sarebbe molto meglio se fosse in formato Q & A anche se stai rispondendo alla tua stessa domanda. –

+0

Il titolo è la domanda. Avrei certamente potuto porre la domanda e rispondere in una risposta separata, ma invece l'ho fatto in questo modo. Questa era la domanda originale che stavo per chiedere ma prima di premere il pulsante Post ho pensato che avrei dovuto fare abbastanza ricerche in modo da poter fare una domanda più "informata". Tuttavia, non mi rendevo conto di quanto tempo quel piccolo sforzo avrebbe finito per prendere. Nel processo, ho risposto alla mia stessa domanda. Poiché ci è voluto così tanto tempo per trovare una soluzione accettabile, ho pensato che sarebbe stato bello salvare gli altri dal dover ripetere tutte le ore di ricerca che dovevo fare. – Dunk

risposta

Problemi correlati