Puedo estar olvidando algo
Usted está.
¿Cuál es la diferencia entre hacer Task.Wait
y await task
?
Pides tu almuerzo del camarero en el restaurante. Un momento después de dar su orden, un amigo entra y se sienta a su lado y comienza una conversación. Ahora tienes dos opciones. Puede ignorar a su amigo hasta que se complete la tarea; puede esperar hasta que llegue su sopa y no hacer nada más mientras espera. O puede responder a su amigo, y cuando su amigo deja de hablar, el camarero le traerá su sopa.
Task.Wait
bloquea hasta que se complete la tarea: ignora a su amigo hasta que se complete la tarea. await
sigue procesando mensajes en la cola de mensajes, y cuando se completa la tarea, pone en cola un mensaje que dice "retomar donde lo dejó después de esperar". Hablas con tu amigo, y cuando hay un descanso en la conversación, llega la sopa.
Task
que demore 10 ms realmente ejecute una duración de 10 horasTask
en su hilo, bloqueándolo durante las 10 horas completas?Para demostrar la respuesta de Eric aquí hay un código:
fuente
//If you press Button2 now you won't see anything in the console until this task is complete and then the label will be updated!
" es engañosa. Al presionar el botón con elt.Wait();
controlador de eventos de clic de botónButtonClick()
no es posible presionar nada y luego ver algo en la consola y actualizar la etiqueta "hasta que se complete esta tarea" ya que la GUI está congelada y no responde, es decir, cualquier clic o interacción con la GUI están siendo PERDIDOS hasta la finalización de la tarea de esperat.Wait
va a bloquear en el hilo principal hasta que se complete la tarea".Este ejemplo demuestra la diferencia muy claramente. Con async / wait, el hilo de llamada no se bloqueará y continuará ejecutándose.
Salida de DoAsTask:
Salida DoAsAsync:
Actualización: ejemplo mejorado al mostrar la ID del hilo en la salida.
fuente
Wait (), hará que se ejecute el código potencialmente asíncrono de manera sincronizada. esperar no lo hará.
Por ejemplo, tiene una aplicación web asp.net. UsuarioA llama / getUser / 1 punto final. El grupo de aplicaciones asp.net elegirá un hilo del grupo de hilos (Thread1) y este hilo hará una llamada http. Si espera Wait (), este hilo se bloqueará hasta que se resuelva la llamada http. Mientras está esperando, si UserB llama / getUser / 2, entonces, el grupo de aplicaciones necesitará servir otro hilo (Thread2) para volver a hacer una llamada http. Acaba de crear (Bueno, en realidad se obtuvo del grupo de aplicaciones) otro subproceso sin razón, porque no puede usar Thread1 que fue bloqueado por Wait ().
Si usa await en Thread1, SyncContext gestionará la sincronización entre Thread1 y la llamada http. Simplemente, notificará una vez que se realice la llamada http. Mientras tanto, si UserB llama / getUser / 2, entonces usará Thread1 nuevamente para hacer una llamada http, porque fue liberada una vez que estaba esperando que la golpearan. Luego, otra solicitud puede usarlo, aún más. Una vez que se realiza la llamada http (usuario1 o usuario2), Thread1 puede obtener el resultado y regresar a la persona que llama (cliente). Thread1 se usó para múltiples tareas.
fuente
En este ejemplo, no mucho, prácticamente. Si está esperando una Tarea que regrese en un subproceso diferente (como una llamada WCF) o ceda el control al sistema operativo (como Archivo IO), esperar usará menos recursos del sistema al no bloquear un subproceso.
fuente
En el ejemplo anterior, puede usar "TaskCreationOptions.HideScheduler" y modificar en gran medida el método "DoAsTask". El método en sí no es asíncrono, como sucede con "DoAsAsync" porque devuelve un valor de "Tarea" y está marcado como "asíncrono", haciendo varias combinaciones, así es como me da exactamente lo mismo que usar "asíncrono / esperar" :
fuente