Async / Await frente a subprocesos

100

En .Net 4.5, Microsoft ha agregado la nueva Async/Awaitfunción para simplificar la codificación asincrónica. Sin embargo, me pregunto

  1. ¿Puede Async/Awaitreemplazar completamente la antigua forma de uso Threads?
  2. ¿Es Async/Awaitcapaz de hacer todo lo que Threadpueda hacer de forma asincrónica?
  3. ¿ Async/AwaitSolo se puede usar con algunos métodos como WebClient.DownloadStringAsynco puedo convertir cualquier método síncrono para que se use Async/Awaity no para bloquear el hilo principal?
Roman Ratskey
fuente
2
Threads y Async / Await son funciones no relacionadas. Puede combinarlos, pero no es necesario.
dtb
2
¡Pensé que Async / Await está haciendo lo mismo que new Thread(() => {Some Work}).Start();está haciendo! no es
Roman Ratskey
2
No Tu suposición no es correcta. Es posible que esté pensando en Task.Run (TPL), que a menudo se combina con Async / Await, pero tampoco está relacionado y no tiene que usarse con él.
dtb
4
@dtb: Entonces, ¿cuándo usar Async / Await y cuándo usar Threads? Estoy realmente confundido acerca de la diferencia entre Task.Run, Thread.Start, Async / Await. Si pudiera darme una buena explicación que me haga entender las diferencias entre ellos, estaría muy agradecido
Roman Ratskey
2
Async / await no crea ni utiliza subprocesos de ninguna otra manera.
wRAR

Respuestas:

78

¿Puede reemplazar completamente la antigua forma de usar Threads?

No. Un hilo puede hacer muchas más cosas útiles. Await está diseñado específicamente para lidiar con algo que toma tiempo, generalmente una solicitud de E / S. Lo que tradicionalmente se hacía con una devolución de llamada cuando se completaba la solicitud de E / S. Escribir código que se base en estas devoluciones de llamada es bastante difícil, await lo simplifica enormemente.

capaz de hacer lo que un hilo puede hacer de forma asincrónica?

Aproximadamente. Await solo se encarga de lidiar con el retraso, de lo contrario no hace nada de lo que hace un hilo. La expresión de espera , que está a la derecha de la palabra clave de espera, es lo que hace el trabajo. Idealmente, no usa un hilo en absoluto, publica una solicitud de controlador y una vez que el controlador completa la transferencia de datos, genera una devolución de llamada de notificación de finalización. La conexión en red es, con mucho, el uso más común, las latencias de cientos de milisegundos son comunes y un efecto secundario inevitable de los servicios que se mueven desde el escritorio o una LAN a "la nube". El uso de estos servicios de forma sincrónica haría que una interfaz de usuario no respondiera.

solo se puede usar con algunos métodos como WebClient.DownloadStringAsync

No. Puede usarlo con cualquier método que devuelva una tarea. Los métodos XxxxAsync () son solo métodos precocinados en el marco .NET para operaciones comunes que requieren tiempo. Como descargar datos de un servidor web.

Hans Passant
fuente
4
En el aspecto moderno de C #, ¿cuál es el mejor enfoque para lograr Async-Callbacks en API externas?
bonCodigo
5
Cubierto en el último párrafo, use una Tarea.
Hans Passant
Esperaría algo que un hilo pueda hacer que no se pueda hacer a través de la programación asíncrona como ejemplo.
Saeed Neamati
1
¿Podría ampliar "Un hilo puede hacer muchas más cosas útiles"? Sería útil comprender las características que proporcionan los subprocesos para las que asyncno son adecuados.
Benjohn
1
Vale la pena mencionarlo await Task.Runpor el trabajo vinculado a la CPU. Si entiendo correctamente, eso a veces logra lo que de otro modo se crearía un hilo, o un trabajador en segundo plano, para hacer.
ToolmakerSteve
15

La declaración oficial sobre esto. Aunque debe comprender las diferencias entre los hilos y la programación asincrónica antes de reemplazar ciegamente una cosa por otras.

GUERRA
fuente
Este es como el primer recurso que he leído sobre Threads y Async / Await que es claro y conciso.
Arman Bimatov
2
Esta respuesta solo contiene un enlace a la documentación. Como el enlace puede quedar desactualizado, la respuesta también puede quedar desactualizada, o incluso peor, completamente inútil. Recomendamos a los usuarios de Stack que publiquen las partes relevantes de los enlaces directamente en su pregunta.
HimBromBeere
1
Lamentablemente, la declaración oficial no explica cuándo hacerlo await Task.Run. Hay una breve mención de Task.Run, pero no está claro. La conclusión es que awaitpor sí solo no hará que una tarea vinculada a la CPU se ejecute en paralelo, por lo tanto, dicho trabajo debe realizarse a través de await Task.Run.
ToolmakerSteve
1

Lo pienso de esta manera (y creo que Microsoft también lo hace si miras https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2012/hh191443(v=vs.110) ) # hilos )

Async / await es una forma rápida de ejecutar código en el subproceso principal de la aplicación con la ventaja de que el código puede suspenderse cuando no tiene trabajo que hacer y devolver el foco al subproceso principal, "despertar" en el subproceso principal cuando hay es un resultado que se debe obtener y luego pasar el procesamiento de nuevo a, lo adivinó, el hilo principal. Piense en ello como una declaración GOTO basada en eventos en Basic que puede pasar el control hacia adelante y hacia atrás a una línea de ejecución específica.

Por el contrario, un hilo es un flujo de ejecución independiente que puede ejecutarse con sus propias variables, etc. donde, dado el hardware suficiente, la ejecución se produce en paralelo al hilo principal.

Si tiene una aplicación GUI que va a descargar un solo archivo y luego hacer algo con ese archivo cuando se descargue, lo implementaría usando un método async / await.

Sin embargo, si su GUI necesita descargar 5000 archivos, crearía un hilo de descarga de archivos para manejar eso, ya que el hilo principal de la GUI puede congelarse mientras se transfiere la ejecución para manejar la descarga de los archivos.

xflowXen
fuente