2012-03-06 5 views
7

Esto es más una pregunta general con respecto a los patrones asincrónicos en C# .NET descritos en MSDN here.En C# .NET, ¿una operación asíncrona crea necesariamente un hilo que bloquea?

Cuando se requiere una larga duración sincrónica operación ser llamado (por ejemplo - WCF, consulta DB, IO, etc), y no quiero que el hilo para bloquear (por ejemplo, - hilo GUI), ¿significa que debe existir otro hilo en alguna parte que haga el bloqueo?

¿El hacer una llamada sincrónicaasíncrono requiere necesariamente un hilo en algún lugar de bloquear?

Por lo tanto, si realizo 10 llamadas asincrónicas de larga duración (que en realidad son 10 llamadas sincrónicas), ¿debe haber 10 subprocesos haciendo la espera? ¿O hay un mecanismo para evitar que se bloqueen 10 hilos?

En WCF, puede crear métodos Begin y End para una llamada WCF para que sea asíncrona. ¿Significa esto que cuando llamo a este método asíncrono, hay un hilo en algún lugar, ya sea en el cliente o en el servidor, que me espera?

He leído varios artículos sobre la variación de métodos para lograr la asincronía, pero estos artículos no explican lo que se hace debajo del capó.

actualización

hice mi pregunta más specifc, ya que soy más acerca interesados ​​en .NET. patrones asíncronos descritos por MSDN.

Actualización 2

reformé la cuestión a ser aún más específico para realizar llamadas sincrónica asincrónica.

Respuesta

7

En .NET Framework, hay muchas maneras de implementar una operación asincrónica: mediante el uso de subprocesos, grupos de subprocesos, métodos BeginXxx y EndXxx, APM basado en eventos o APM basado en tareas.

Cada patrón asincrónico tiene su propia implementación interna y todos estos modelos programación asincrónica se explican en este blog article, incluyendo el patrón tradicional asíncrono BeginXxx y EndXxx.

A continuación es el resumen de todos los patrones asincrónicos para una referencia rápida: Async Summary:

Por otra parte, Jeffrey Richter también explica la CLR Asynchronous Programming Model en MSDN Magazine muy bien.

+0

Gran enlace al artículo. Por lo tanto, no lo dice explícitamente, pero parece que se trata de llamadas asincrónicas de bajo nivel, esto se hace sin bloquear hilos. Pero si quiere hacer una llamada sincronizada asincrónica, debe crearse una cadena. Estoy en lo cierto en esto? – Mas

+0

@Mas Crear un 'Thread' es solo una forma de hacerlo asincrónico. Como se explicó en el Resumen en respuesta, hay otras maneras de convertir sus llamadas de sincronización a llamadas asíncronas. – VS1

+0

De acuerdo con la tabla, todos los Patrones de Asincronización se basan en subprocesos (las Tareas también usan subprocesos en el fondo). – Mas

2

Desafortunadamente, no hay una sola respuesta a esto. Algunas bibliotecas proporcionan operaciones asincrónicas implementadas de forma nativa, como por ejemplo sockets, en los que es compatible con el hardware. Puede que otros no lo hagan, como una biblioteca de terceros que podría bloquear.

3

No es necesariamente un hilo por operación. Como dice @Ioannis Karadimas, esto probablemente depende de la implementación.

Por ejemplo, imagine que quiero hacer async recibe desde 10 sockets diferentes. Esto se puede lograr con un solo hilo adicional usando una llamada para seleccionar en un bucle, que no deterministicamente selecciona un zócalo disponible cuando se recibe un mensaje.

2

'Entonces, si realizo 10 llamadas asincrónicas de larga ejecución, ¿debe haber 10 hilos haciendo la espera?' En general, no.

'¿Existe un mecanismo para evitar el bloqueo de 10 hilos?' - hay mecanismos para permitir que 1 hilo de bloqueo procese varios elementos. Ejemplo simple: un hilo del núcleo puede esperar en una señal de NIC y en un semáforo de cola de entrada; normalmente está bloqueado esperando uno u otro. Su aplicación de usuario asíncrona pone en cola un envío de red y el hilo del núcleo lo obtiene de la cola e intenta enviarlo al hardware de la tarjeta de red. Si no puede, lo agrega a una cola de envío interno y regresa a su aplicación con una respuesta 'WOULD_BLOCK'. Cuando el hardware está listo, señala el hilo del núcleo, que elimina el buffer de envío y lo carga en el hardware.Del mismo modo, su aplicación envía en una, o más, solicitudes asíncronas recv(), (con búferes), y el hilo del kernel lo agrega a una lista y lo regresa con una respuesta 'WOULD_BLOCK'. Cuando los datos entran en la NIC, su controlador señala y el hilo del kernel inspecciona los datos e intenta encontrar una entrada en su lista que está esperando esos datos. Si se trata de datos para su aplicación, copia/DMA los datos del hardware en sus buffers y llama a su devolución de llamada asincrónica (tenga en cuenta cómo se llama exactamente a su llamada a llamada asycn y en qué hilo depende el sistema operativo. está en cola hasta su subproceso GUI, o una estructura de finalización IOCP está en cola hasta un grupo de subprocesos de usuario).

De todos modos, el punto es que el hilo del kernel puede tener muchas entradas de muchos procesos en su lista de envío interno o en la lista de elementos recv. Cuando el hardware, o su cola de entrada, requieren atención, se ejecuta y maneja, de lo contrario permanece bloqueado.

1

No habrá ningún Hilo EN ESPERA si realiza una llamada Async utilizando las bibliotecas de Framework. por ej. Como en su caso de uso, ha mencionado "En WCF, puede crear métodos Begin y End para una llamada WCF para que sea asíncrona. ¿Esto significa que cuando llamo a este método asíncrono, hay un hilo en alguna parte, ya sea en el cliente o el servidor, ¿eso me espera? "

No habrá ningún hilo de espera para la operación asincrónica para ser completado, para más detalles se puede comprobar este excelente blog http://blog.stephencleary.com/2013/11/there-is-no-thread.html

Cuestiones relacionadas