socket - Comunicación TCP asíncrona en.NET
system net sockets (4)
Pregunta rápida aquí: ¿hay algún beneficio obvio para usar comunicación asincrónica con la clase NetworkStream (generada por TcpClient), es decir, los métodos BeginRead / BeginWrite en lugar de ejecutar un hilo separado y usar operaciones síncronas en eso, es decir, leer / escribir? Mi impresión ha sido (podría ser bastante erróneo) que las operaciones asíncronas no sean de bloqueo y se realicen a nivel del sistema operativo (¿quizás en la pila TCP?), Con un elemento del grupo de subprocesos para la devolución de llamada. Estoy pensando que seguramente debe ser diferente de llamar a ThreadPool.QueueUserWorkItem en el método síncrono, o que tendría poco sentido proporcionarlo. Ahora, estoy bastante seguro de que este es el tipo de cosas (llamadas a nivel de sistema operativo) que ocurre al menos para la E / S de archivos, pero si alguien pudiera aclarar el asunto con respecto a la comunicación de red (TCP), sería de gran ayuda. Básicamente, me gustaría saber si hay algún beneficio específico para cualquiera de los métodos (además del obvio de poder usar las clases BinaryReader / StreamReader con las llamadas sincrónicas).
Existe una diferencia: si utiliza un hilo de trabajo para llamar a la versión síncrona, deberá atar uno de los hilos en una llamada de bloqueo.
Mientras que los métodos Begin no vinculan un hilo sino que utilizan una devolución de llamada en una señal de E / S apropiada, la devolución de llamada se ejecutará en un hilo del grupo.
Estoy de acuerdo con AnthonyWJones, imagine que su grupo de subprocesos tiene 10 subprocesos, pero tiene 100 clientes pasivos. Con las llamadas asincrónicas, puede comenzar con ReadRead para cada una de ellas, y cuando los datos de alguien estén listos, serán procesados por uno de los subprocesos del grupo. Pero si intenta utilizar QueueUserWorkItem, programará la recepción de datos de solo 10 clientes. Y si no envían nada en 1 hora, otros 90 clientes nunca tendrán la oportunidad de obtener datos.
No estoy seguro de por qué NetworkStream incluso tiene BeginRead / Write, ya que básicamente viola el propósito de NetworkStream en primer lugar. Al utilizar los métodos Async, obtienes una respuesta más rápida, una mayor escalabilidad y un consumo reducido de recursos.
Si solo vas a tener una conexión a la vez, entonces no importa mucho si utilizas un hilo de grupo de subprocesos o no, pero si aceptas muchas conexiones, definitivamente querrás usar asincrónico.
Como han señalado otros, la asignación de otro hilo a su proceso lo afectará cuando use el método síncrono a medida que aumente la cantidad de conexiones simultáneas.
Sin embargo, si sabes que solo tendrás un pequeño número de conexiones, diría que se convierte en un lavado y debes elegir el método más natural para tu aplicación.
En el caso en que la carga del hilo sea insignificante, esperaría que los dos escenarios se desarrollaran de esta manera.
Asincrónico:
- Realiza una llamada a BeginRead / BeginWrite
- "El sistema" (framework / OS) está informado de lo que quiere
- Lectura / escritura completa
- "El sistema" le dice a un hilo en el grupo de subprocesos que llame a su devolución de llamada
- Haz lo que necesites para completar la operación
Sincrónico en otro hilo:
- Obtiene un hilo del grupo de subprocesos para manejar el IO
- Usted hace una llamada para leer / escribir
- "El sistema" (framework / OS) está informado de lo que quiere
- Lectura / escritura completa
- Haz lo que necesites para completar la operación
La única diferencia aquí es que el paso 4 de la llamada asincrónica se convierte en el paso 1 en el sincrónico en otro caso de subprocesos.