En los últimos días he probado las nuevas características de .net 4.5 y c # 5.
Me gustan sus nuevas funciones async / wait. Anteriormente había usado BackgroundWorker para manejar procesos más largos en segundo plano con una interfaz de usuario receptiva.
Mi pregunta es: después de tener estas nuevas características agradables, ¿cuándo debo usar async / await y cuándo un BackgroundWorker ? ¿Cuáles son los escenarios comunes para ambos?
Respuestas:
async / await está diseñado para reemplazar construcciones como
BackgroundWorker
. Si bien ciertamente puede usarlo si lo desea, debería poder usar async / wait, junto con algunas otras herramientas TPL, para manejar todo lo que existe.Dado que ambos funcionan, todo se reduce a la preferencia personal de cuál usar cuando. ¿Qué es más rápido para ti ? Lo que es más fácil para que usted pueda entender?
fuente
async
/await
también permite la programación asincrónica sin hilos de grupo de subprocesos.Esto es probable TL; DR para muchos, pero creo que comparar
await
conBackgroundWorker
es como comparar manzanas y naranjas y mis pensamientos sobre esto son los siguientes:BackgroundWorker
está destinado a modelar una única tarea que desea realizar en segundo plano, en un subproceso de grupo de subprocesos.async
/await
es una sintaxis para esperar asincrónicamente operaciones asincrónicas. Esas operaciones pueden o no usar un subproceso de grupo de subprocesos o incluso usar cualquier otro subproceso . Entonces, son manzanas y naranjas.Por ejemplo, puede hacer algo como lo siguiente con
await
:Pero, probablemente nunca modelarías eso en un trabajador en segundo plano, probablemente harías algo como esto en .NET 4.0 (antes
await
):Observe la desunión de la eliminación en comparación entre las dos sintaxis y cómo no puede usar
using
sinasync
/await
.Pero, no harías algo así con eso
BackgroundWorker
.BackgroundWorker
Por lo general, es para modelar una sola operación de larga duración que no desea afectar la capacidad de respuesta de la interfaz de usuario. Por ejemplo:Realmente no hay nada allí con lo que pueda usar async / wait,
BackgroundWorker
está creando el hilo para usted.Ahora, podría usar TPL en su lugar:
En cuyo caso,
TaskScheduler
está creando el hilo para usted (asumiendo el valor predeterminadoTaskScheduler
), y podría usarawait
lo siguiente:En mi opinión, una comparación importante es si estás informando progreso o no. Por ejemplo, puede tener
BackgroundWorker like
esto:Pero no se ocuparía de algo de esto porque arrastraría y soltaría el componente de trabajador de fondo en la superficie de diseño de un formulario, algo que no puede hacer con
async
/await
yTask
... es decir, ganó ' t cree manualmente el objeto, establezca las propiedades y configure los controladores de eventos. solo llenarías el cuerpo de laDoWork
,RunWorkerCompleted
yProgressChanged
los controladores de eventos.Si "convertiste" eso en asíncrono / espera, harías algo como:
Sin la capacidad de arrastrar un componente a una superficie de diseñador, realmente depende del lector decidir cuál es "mejor". Pero, para mí, esa es la comparación entre
await
yBackgroundWorker
no si puedes esperar métodos incorporados comoStream.ReadAsync
. por ejemplo, si estaba usandoBackgroundWorker
según lo previsto, podría ser difícil de convertir para usarawait
.Otros pensamientos: http://jeremybytes.blogspot.ca/2012/05/backgroundworker-component-im-not-dead.html
fuente
var t1 = webReq.GetResponseAsync(); var t2 = webReq2.GetResponseAsync(); await t1; await t2;
. Lo que esperaría dos operaciones paralelas. Aguardar es mucho mejor para tareas asincrónicas, pero secuenciales, OMI ...await Task.WhenAny(t1, t2)
hacer algo cuando la tarea se completara primero. Es probable que desee un bucle para asegurarse de que la otra tarea también se complete. Por lo general, desea saber cuándo se completa una tarea específica , lo que lo lleva a escribirawait
s secuenciales .Esta es una buena introducción: http://msdn.microsoft.com/en-us/library/hh191443.aspx La sección Hilos es justo lo que está buscando:
fuente
BackgroundWorker está explícitamente etiquetado como obsoleto en .NET 4.5:
El artículo de MSDN "Programación asincrónica con asíncrono y espera (C # y Visual Basic)" dice:
ACTUALIZAR
"para operaciones vinculadas a IO porque el código es más simple y no tiene que protegerse contra las condiciones de carrera" ¿Qué condiciones de carrera pueden ocurrir, podría dar un ejemplo? "
Esta pregunta debería haberse puesto como una publicación separada.
Wikipedia tiene una buena explicación de las condiciones de carrera . La parte necesaria es multiproceso y del mismo artículo de MSDN Programación asincrónica con asíncrono y espera (C # y Visual Basic) :
Es decir, "Las palabras clave asíncronas y en espera no hacen que se creen hilos adicionales".
Hasta donde puedo recordar mis propios intentos cuando estaba estudiando este artículo hace un año, si ha ejecutado y jugado con código de muestra del mismo artículo, podría encontrar situaciones que no sean asincrónicas (podría intentar convertir para ti) ¡bloquea indefinidamente!
Además, para ejemplos concretos, puede buscar en este sitio. Aquí hay algunos ejemplos:
fuente