2012-06-01 17 views
25

Después de pasar mucho más tiempo de lo que parece razonable para encontrar una respuesta a esta simple pregunta, pensé que dejaría mis resultados aquí para que otros no tengan que pasar por todos los aros y caminos equivocados que Yo acababa de seguir.Cómo usar correctamente TcpClient ReadTimeout

El problema es que si usa la propiedad TcpClient ReadTimeout y su operación de lectura agota el tiempo de espera, Microsoft decidió cerrar el socket. Esto no se espera, no es deseable, no se realiza con ninguna otra implementación de socket que conozca, y no tiene una razón válida para que este sea el caso aparte de la pereza del programador. Pero esto es lo que Microsoft eligió hacer.

De todos modos, todas las soluciones provisionales que encontré, incluso en este sitio, tenían varias formas de realizar alguna forma de votación ocupada y algunas incluso implicaban iniciar otro hilo para realizar una simple llamada de Lectura. Lo siento, pero tengo mejores cosas que hacer con mi CPU que sentarme allí y estar ocupado, especialmente con muchos enchufes abiertos, así que esta no es una opción para mí. Después de todo, esto no es a principios de la década de 1990, donde las encuestas ocupadas eran solo la forma en que hacía las cosas. Hoy en día, tenemos esto llamado sistemas operativos que se ocupan de este tipo de cosas de manera bastante eficiente utilizando interrupciones.

De todas formas, en otra búsqueda tangencial me encontré con este viejo blog:

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

MSDN Blogs> Blog de Mike Flasko> Manejo de un tiempo de espera al leer datos de la red

Los aways de llaves se que le dirá la solución sobre cómo manejar correctamente los tiempos de espera de lectura son:

En este punto uno puede estar tentado de atrapar la excepción y luego vuelva a emitir la lectura en el mismo NetworkStream. Esta estrategia puede conducir a errores inesperados. Lo mejor que puede hacer ahora es tratar el NetworkStream (socket) como si estuviera en un estado inestable. Esto se debe a que cuando la pila subyacente expira, la lectura de E/S subyacente se cancela. Si los datos entran al mismo tiempo, los datos se perderán, lo que provocará una transmisión de datos dañada.

y la solución:

Un mejor enfoque consiste en detectar la excepción, cerrar la toma de corriente o TCPClient y volver a conectar, si es necesario.

Mientras sigo creyendo que esto supone una carga innecesaria para el usuario de la API, al menos es la solución más adecuada que pude encontrar entre las docenas de sitios que intenté imaginar para hacer una toma semi-adecuada ReadTimeout.

Espero que esta pregunta/comentario le ahorre a alguien las horas que tardé en encontrar.

+0

he estado trabajando con esas cosas últimamente también, si configuro el tiempo de espera en 1000 ms y atrapo la excepción, a veces puedo terminar retrasando algunos procedimientos, porque es bastante difícil determinar si la transmisión realmente ha terminado o si tiene un problema de red.Por ejemplo, tengo una parte del código que transmite una imagen PNG a través de la red, el código es algo así como while (verdadero) {intente Recibir datos y ponerlo en un búfer de 4096 bytes en la excepción; luego, si no hay datos disponibles, rompa; } Si no pongo un hilo de 1ms en reposo, (sé que es una mierda), el dato disponible se devolverá falso demasiado pronto y la imagen se dañará. – Felype

+0

¿Es esta una pregunta? Siento que esto sería mucho mejor si estuviera en formato de preguntas y respuestas, incluso si está respondiendo su propia pregunta. –

+0

El título es la pregunta. Ciertamente podría haber hecho la pregunta y respondido en una respuesta separada, pero lo hice de esta manera. Esta fue la pregunta original que iba a hacer, pero antes de presionar el botón Publicar pensé que debería investigar lo suficiente para poder hacer una pregunta más "informada". Sin embargo, no me di cuenta de cuánto tiempo tomaría ese pequeño esfuerzo. En el proceso, respondí mi propia pregunta. Como me llevó mucho tiempo encontrar una solución aceptable, pensé que sería bueno evitar que otros tuvieran que repetir todas las horas de investigación que tenía que hacer. – Dunk

Respuesta

Cuestiones relacionadas