Según tengo entendido, una de las principales cosas que hacer async
yawait
hacer es hacer que el código sea fácil de escribir y leer, pero ¿es igual usarlos para generar hilos de fondo para realizar una lógica de larga duración?
Actualmente estoy probando el ejemplo más básico. He agregado algunos comentarios en línea. ¿Me lo puedes aclarar?
// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
Task<int> access = DoSomethingAsync();
// task independent stuff here
// this line is reached after the 5 seconds sleep from
// DoSomethingAsync() method. Shouldn't it be reached immediately?
int a = 1;
// from my understanding the waiting should be done here.
int x = await access;
}
async Task<int> DoSomethingAsync()
{
// is this executed on a background thread?
System.Threading.Thread.Sleep(5000);
return 1;
}
c#
.net
asynchronous
async-await
Dan Dinu
fuente
fuente
Respuestas:
Cuando se usa
async
yawait
el compilador genera una máquina de estado en segundo plano.Aquí hay un ejemplo en el que espero poder explicar algunos de los detalles de alto nivel que están sucediendo:
Bien, entonces, ¿qué pasa aquí?
Task<int> longRunningTask = LongRunningOperationAsync();
comienza a ejecutarseLongRunningOperation
Se realiza un trabajo independiente en supongamos que
await longRunningTask
se alcanza el subproceso principal (ID del subproceso = 1) .Ahora, si el
longRunningTask
no ha terminado y todavía se está ejecutando,MyMethodAsync()
volverá a su método de llamada, por lo que el hilo principal no se bloqueará. CuandolongRunningTask
finalice, un hilo del ThreadPool (puede ser cualquier hilo) volverá aMyMethodAsync()
su contexto anterior y continuará la ejecución (en este caso, imprimirá el resultado en la consola).Un segundo caso sería que
longRunningTask
ya ha finalizado su ejecución y el resultado está disponible. Al llegar a laawait longRunningTask
ya tenemos el resultado, por lo que el código continuará ejecutándose en el mismo hilo. (en este caso, imprimir el resultado a la consola). Por supuesto, este no es el caso para el ejemplo anterior, donde hay unTask.Delay(1000)
involucrado.fuente
Deben hacer que el código asincrónico sea fácil de escribir y leer, sí.
De ningún modo.
La
async
palabra clave habilita laawait
palabra clave. Por lo tanto, cualquier método que useawait
debe estar marcadoasync
.No, porque los
async
métodos no se ejecutan en otro subproceso de forma predeterminada.No.
Puede encontrar mi
async
/await
introducción útil. Los documentos oficiales de MSDN también son inusualmente buenos (particularmente la sección TAP ), y elasync
equipo publicó una excelente pregunta frecuente .fuente
async
métodos no se ejecutan en otro hilo de manera predeterminada. En su ejemplo, laSleep()
llamada dentroDoSomethingAsync()
bloquea el hilo actual que impide que la ejecución continúe dentrobutton1_Click()
hasta que seDoSomethingAsync()
complete. Tenga en cuenta que mientrasThread.Sleep()
bloquea el hilo de ejecución,Task.Delay() does not.
Explicación
Aquí hay un ejemplo rápido de
async
/await
a un alto nivel. Hay muchos más detalles para considerar más allá de esto.Nota:
Task.Delay(1000)
simula hacer trabajo durante 1 segundo. Creo que es mejor pensar en esto como esperar una respuesta de un recurso externo. Como nuestro código está esperando una respuesta, el sistema puede dejar de lado la tarea en ejecución y volver a ella una vez que haya terminado. Mientras tanto, puede hacer otro trabajo en ese hilo.En el siguiente ejemplo, el primer bloque está haciendo exactamente eso. Comienza todas las tareas inmediatamente (las
Task.Delay
líneas) y las pone a un lado. El código se detendrá en laawait a
línea hasta que se haya realizado el retraso de 1 segundo antes de pasar a la siguiente línea. Dado queb
,c
,d
, ye
todo empezó ejecutar casi en el mismo momento exacto en quea
(debido a la falta de la Await), deben terminar más o menos al mismo tiempo en este caso.En el siguiente ejemplo, el segundo bloque está iniciando una tarea y esperando a que termine (eso es lo que
await
hace) antes de comenzar las tareas posteriores. Cada iteración de esto lleva 1 segundo. Elawait
está pausando el programa y esperando el resultado antes de continuar. Esta es la principal diferencia entre el primer y el segundo bloque.Ejemplo
SALIDA:
Información adicional sobre SynchronizationContext
Nota: Aquí es donde las cosas se ponen un poco confusas para mí, así que si me equivoco en algo, corríjame y actualizaré la respuesta. Es importante tener una comprensión básica de cómo funciona esto, pero puede sobrevivir sin ser un experto en él, siempre que nunca lo use
ConfigureAwait(false)
, aunque supongo que probablemente perderá alguna oportunidad de optimización.Hay un aspecto de esto que hace que el concepto
async
/ seaawait
algo más difícil de entender. Ese es el hecho de que en este ejemplo, todo esto está sucediendo en el mismo hilo (o al menos lo que parece ser el mismo hilo en lo que respecta a suSynchronizationContext
). Por defecto,await
restaurará el contexto de sincronización del hilo original en el que se estaba ejecutando. Por ejemplo, en ASP.NET tiene un elementoHttpContext
que está vinculado a un hilo cuando entra una solicitud. Este contexto contiene elementos específicos de la solicitud Http original, como el objeto Solicitud original que tiene elementos como idioma, dirección IP, encabezados, etc. Si cambia los hilos a la mitad del procesamiento de algo, podría terminar tratando de extraer información de este objeto en otroHttpContext
que podría ser desastroso Si sabe que no usará el contexto para nada, puede optar por "no importarle". Básicamente, esto permite que su código se ejecute en un hilo separado sin traer el contexto.¿Cómo lo logras? De manera predeterminada, el
await a;
código en realidad supone que DESEA capturar y restaurar el contexto:Si desea permitir que el código principal continúe en un nuevo hilo sin el contexto original, simplemente use falso en lugar de verdadero para que sepa que no necesita restaurar el contexto.
Una vez que el programa termina de pausarse, continuará potencialmente en un hilo completamente diferente con un contexto diferente. Aquí es de donde vendría la mejora del rendimiento: podría continuar en cualquier subproceso disponible sin tener que restaurar el contexto original con el que comenzó.
¿Es esto algo confuso? ¡Demonios si! ¿Puedes resolverlo? ¡Probablemente! Una vez que tenga una idea de los conceptos, continúe con las explicaciones de Stephen Cleary, que tienden a orientarse más hacia alguien con una comprensión técnica de
async
/await
ya.fuente
await MethodCall()
es un desperdicio absoluto? También podrías soltar elawait
/async
?await
, creo que libera el hilo de nuevo al grupo en lugar de retenerlo. Esto lo hace disponible para su uso en otros lugares mientras espera el regreso de la TareaAdemás de las otras respuestas, eche un vistazo a wait (referencia de C #)
y más específicamente en el ejemplo incluido, explica un poco su situación
fuente
Task.Delay
dispare el temporizador .Mostrando las explicaciones anteriores en acción en un programa de consola simple:
Y la salida es:
Así,
TestAsyncAwaitMethods
. Eso regresa inmediatamente sin detener el hilo actual e inmediatamente vemos el mensaje 'Presione cualquier tecla para salir'LongRunningMethod
está ejecutando en segundo plano. Una vez completado, otro hilo de Threadpool recoge este contexto y muestra el mensaje finalPor lo tanto, no se bloquea el hilo.
fuente
return 1
parte merece una explicación adicional: laawait
palabra clave le permite devolver el tipo subyacente de formaTask<T>
directa, lo que facilita la adaptación del código existente al mundo de espera / asíncrono . Pero no tiene que devolver un valor, ya que es posible devolver unTask
sin especificar un tipo de retorno, que sería el equivalente de unvoid
método sincrónico . Tenga en cuenta que C # permiteasync void
métodos, pero debe evitar hacerlo a menos que esté abordando controladores de eventos.Creo que has elegido un mal ejemplo con
System.Threading.Thread.Sleep
El punto de una
async
tarea es dejar que se ejecute en segundo plano sin bloquear el hilo principal, como hacer unDownloadFileAsync
System.Threading.Thread.Sleep
no es algo que se está "haciendo", simplemente duerme y, por lo tanto, se llega a su siguiente línea después de 5 segundos ...Lea este artículo, creo que es una gran explicación
async
yawait
concepto: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspxfuente
Thread.Sleep
bloquea el hilo (el hilo no puede hacer nada más que permanecer inactivo), pero un método asíncrono no. En el caso deDownloadFileAsync
, el hilo puede ir y hacer otra cosa hasta que llegue una respuesta del servidor remoto. Un mejor marcador de posición para "alguna tarea que lleva tiempo" en un método asíncrono esTask.Delay
, ya que en realidad es asíncrono.async
palabra clave. Pero su método todavía se ejecutaba sincrónicamente, y esta respuesta explicaba perfectamente por qué: porque en realidad no ejecutaba ningún código asincrónico. Los métodos marcadosasync
siguen ejecutándose sincrónicamente hasta que estéawait
incompletoTask
. Si no hayawait
, entonces el método se ejecuta sincrónicamente y el compilador le advertirá de eso.Aquí hay un programa de consola rápido para dejar en claro a los que siguen. El
TaskToDo
método es su método de larga ejecución que desea hacer asíncrono. Hacer que se ejecute de forma asincrónica se realiza mediante elTestAsync
método. El método de bucles de prueba solo ejecuta lasTaskToDo
tareas y las ejecuta de forma asíncrona. Puede ver eso en los resultados porque no se completan en el mismo orden de ejecución a ejecución: informan al hilo de la interfaz de usuario de la consola cuando se completan. Simplista, pero creo que los ejemplos simplistas resaltan el núcleo del patrón mejor que los ejemplos más involucrados:fuente
Para un aprendizaje más rápido ...
Comprender el flujo de ejecución del método (con un diagrama): 3 minutos
Pregunta introspección (aprendizaje): 1 min.
Pasar rápidamente la sintaxis de azúcar: 5 minutos
Comparta la confusión de un desarrollador: 5 minutos
Problema: cambie rápidamente una implementación real del código normal a código asíncrono: 2 minutos
¿A dónde seguir?
Comprender el flujo de ejecución del método (con un diagrama): 3 minutos
En esta imagen, solo concéntrate en el n. ° 6 (nada más)
En el paso n. ° 6: la ejecución se detuvo aquí porque se ha quedado sin trabajo. Para continuar necesita un resultado de getStringTask (una especie de función). Por lo tanto, utiliza un
await
operador para suspender su progreso y devolver el control (rendimiento) a la persona que llama (de este método en el que estamos). La llamada real a getStringTask se realizó anteriormente en el n. ° 2. En el n. ° 2 se hizo una promesa de devolver un resultado de cadena. ¿Pero cuándo devolverá el resultado? ¿Deberíamos (# 1: AccessTheWebAsync) hacer una segunda llamada nuevamente? Quién obtiene el resultado, # 2 (declaración de llamada) o # 6 (declaración de espera)El llamador externo de AccessTheWebAsync () también está esperando ahora. Entonces, la persona que llama esperando AccessTheWebAsync, y AccessTheWebAsync está esperando GetStringAsync en este momento. Lo interesante es que AccessTheWebAsync trabajó un poco antes de esperar (# 4) quizás para ahorrar tiempo de espera. ¡La misma libertad para realizar múltiples tareas también está disponible para la persona que llama externa (y para todas las personas que llaman en la cadena) y esta es la mayor ventaja de esta cosa 'asincrónica'! Sientes que es sincrónico ... o normal, pero no lo es.
Recuerde, el método ya fue devuelto (# 2), no puede regresar nuevamente (sin segunda vez). Entonces, ¿cómo sabrá la persona que llama? ¡Se trata de tareas! La tarea fue aprobada. Se esperaba la tarea (sin método, sin valor). El valor se establecerá en la tarea. El estado de la tarea se configurará para completar. La persona que llama solo monitorea la Tarea (# 6). Entonces 6 # es la respuesta a dónde / quién obtiene el resultado. Más lecturas para más tarde aquí .
Pregunta introspección para aprender bien: 1 min
Ajustemos un poco la pregunta:
Porque el aprendizaje
Task
cubre automáticamente los otros dos (y responde a su pregunta)Pasar rápidamente la sintaxis de azúcar: 5 minutos
Antes de la conversión (método original)
internal static int Method(int arg0, int arg1) { int result = arg0 + arg1; IO(); // Do some long running IO. return result; }
un método de tarea para llamar al método anterior
internal static Task<int> MethodTask(int arg0, int arg1) { Task<int> task = new Task<int>(() => Method(arg0, arg1)); task.Start(); // Hot task (started task) should always be returned. return task; }
¿Mencionamos esperar o asíncrono? No. Llame al método anterior y obtendrá una tarea que puede monitorear. Ya sabes lo que devuelve la tarea ... un número entero.
Llamar a una tarea es un poco complicado y es cuando las palabras clave comienzan a aparecer. Llamemos MethodTask ()
internal static async Task<int> MethodAsync(int arg0, int arg1) { int result = await HelperMethods.MethodTask(arg0, arg1); return result; }
Mismo código de arriba agregado como imagen de abajo:
await
async
(sintaxis obligatoria)Async
como prefijo (estándar de codificación)await
es fácil de entender pero los dos restantes (async
,Async
) pueden no ser :). Así, se debe hacer mucho más sentido para el compilador lee though.Further para más adelante aquíComparta la confusión de un desarrollador: 5 minutos
Un desarrollador ha cometido un error al no implementar, ¡
Task
pero aún funciona! Intente comprender la pregunta y solo la respuesta aceptada que se proporciona aquí . Espero que hayas leído y entendido completamente. El resumen es que es posible que no veamos / implementemos 'Tarea' pero se implementa en algún lugar de una clase principal. Del mismo modo, en nuestro ejemplo, llamar a un ya construidoMethodAsync()
es mucho más fácil que implementar ese método con unTask
(MethodTask()
) nosotros mismos. A la mayoría de los desarrolladores les resulta difícil entenderTasks
cómo convertir un código a uno asíncrono.Consejo: intente encontrar una implementación Async existente (como
MethodAsync
oToListAsync
) para externalizar la dificultad. Por lo tanto, solo tenemos que lidiar con Async y esperar (que es fácil y bastante similar al código normal)Problema: cambie rápidamente una implementación del mundo real de código normal a operación asíncrona: 2 minutos
La línea de código que se muestra a continuación en la Capa de datos comenzó a romperse (en muchos lugares). Porque actualizamos parte de nuestro código de .Net framework 4.2. * A .Net core. ¡Tuvimos que arreglar esto en 1 hora en toda la aplicación!
¡pan comido!
Async
yawait
de código.la línea del código de llamada se cambió así
La firma del método cambió de
Contract GetContract(int contractnumber)
a
async Task<Contract> GetContractAsync(int contractnumber)
el método de llamada también se vio afectado:
GetContractAsync(123456);
fue llamado comoGetContractAsync(123456).Result;
¡Lo cambiamos por todas partes en 30 minutos!
¡Pero el arquitecto nos dijo que no usáramos la biblioteca EntityFramework solo para esto! ¡Uy! ¡drama! Luego hicimos una implementación de Tarea personalizada (yuk). Que ya sabes cómo. Sigue siendo fácil! .. todavía yuk ..
¿A dónde seguir? Hay un maravilloso video rápido que podríamos ver sobre la conversión de llamadas síncronas a asíncronas en ASP.Net Core , quizás esa sea la dirección que tomaría después de leer esto.
fuente
Todas las respuestas aquí usan
Task.Delay()
o alguna otraasync
función incorporada. Pero aquí está mi ejemplo que no usa ninguna de esasasync
funciones:fuente
task.Wait();
y cómo se puede utilizar para evitar asíncrono / demonios esperan: PEsta respuesta tiene como objetivo proporcionar información específica de ASP.NET.
Al utilizar async / await en el controlador MVC, es posible aumentar la utilización del grupo de subprocesos y lograr un rendimiento mucho mejor, como se explica en el siguiente artículo,
http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4
fuente
Asíncrono y espera explicación simple
Analogia simple
Una persona puede esperar su tren matutino. Esto es todo lo que están haciendo, ya que esta es su tarea principal que están realizando actualmente. (programación síncrona (¡lo que normalmente haces!))
Otra persona puede esperar su tren matutino mientras fuma un cigarrillo y luego toma su café. (Programación asincrónica)
¿Qué es la programación asincrónica?
La programación asincrónica es donde un programador elegirá ejecutar parte de su código en un hilo separado del hilo principal de ejecución y luego notificará al hilo principal cuando se complete.
¿Qué hace realmente la palabra clave asíncrona?
Prefijar la palabra clave asíncrona a un nombre de método como
permite al programador usar la palabra clave wait al llamar a tareas asincrónicas. Eso es todo lo que hace.
¿Porque es esto importante?
En muchos sistemas de software, el hilo principal está reservado para operaciones específicamente relacionadas con la interfaz de usuario. Si estoy ejecutando un algoritmo recursivo muy complejo que tarda 5 segundos en completarse en mi computadora, pero lo estoy ejecutando en el subproceso principal (subproceso de interfaz de usuario) Cuando el usuario intenta hacer clic en cualquier cosa de mi aplicación, parecerá congelado ya que mi hilo principal se ha puesto en cola y actualmente está procesando demasiadas operaciones. Como resultado, el hilo principal no puede procesar el clic del mouse para ejecutar el método desde el clic del botón.
¿Cuándo usas Async y Await?
Utilice las palabras clave asincrónicas idealmente cuando esté haciendo algo que no implique la interfaz de usuario.
Digamos que está escribiendo un programa que permite al usuario dibujar en su teléfono móvil, pero cada 5 segundos verificará el clima en Internet.
Deberíamos estar esperando la llamada que la encuesta llama cada 5 segundos a la red para conocer el clima, ya que el usuario de la aplicación necesita seguir interactuando con la pantalla táctil del móvil para dibujar imágenes bonitas.
¿Cómo se usa Async y Await?
Siguiendo con el ejemplo anterior, aquí hay un pseudocódigo de cómo escribirlo:
Notas adicionales - Actualización
Olvidé mencionar en mis notas originales que en C # solo puede esperar los métodos que están envueltos en Tareas. por ejemplo, puede esperar este método:
No puede esperar métodos que no sean tareas como esta:
No dude en revisar el código fuente de la clase Task aquí .
fuente
Asíncrono / Aguardar
En realidad, Async / Await son un par de palabras clave que son simplemente azúcar sintáctica para crear una devolución de llamada de una tarea asincrónica.
Tomemos como ejemplo esta operación:
El código anterior tiene varias desventajas. Los errores no se transmiten y es difícil de leer. Pero Async y Await vienen a ayudarnos:
Las llamadas en espera deben estar en métodos asíncronos. Esto tiene algunas ventajas:
NOTA : Async y Await se usan con llamadas asincrónicas para no realizarlas. Tienes que usar Task Libary para esto, como Task.Run ().
Aquí hay una comparación entre soluciones de espera y ninguna de espera
Esta es la solución no asíncrona:
Este es el método asíncrono:
En realidad, puede llamar a un método asíncrono sin la palabra clave wait pero esto significa que cualquier Excepción aquí se traga en el modo de liberación:
Async y Await no son para computación paralela. Se utilizan para no bloquear su hilo principal. Cuando se trata de asp.net o aplicaciones de Windows, bloquear su hilo principal debido a una llamada de red es algo malo. Si haces esto, tu aplicación no responderá o incluso se bloqueará.
Echa un vistazo a ms docs para más ejemplos.
fuente
Para ser honesto, sigo pensando que la mejor explicación es la del futuro y las promesas en Wikipedia: http://en.wikipedia.org/wiki/Futures_and_promises
La idea básica es que tiene un grupo separado de subprocesos que ejecutan tareas de forma asincrónica. Al usarlo. Sin embargo, el objeto promete que ejecutará la operación en algún momento y le dará el resultado cuando lo solicite. Esto significa que se bloqueará cuando solicite el resultado y no haya terminado, pero de lo contrario se ejecutará en el grupo de subprocesos.
A partir de ahí, puede optimizar las cosas: algunas operaciones se pueden implementar de forma asíncrona y puede optimizar cosas como la E / S de archivos y la comunicación de red agrupando las solicitudes posteriores y / o reordenándolas. No estoy seguro de si esto ya está en el marco de tareas de Microsoft, pero si no lo fuera, sería una de las primeras cosas que agregaría.
En realidad, puede implementar el tipo de patrón futuro con rendimientos en C # 4.0. Si desea saber exactamente cómo funciona, puedo recomendar este enlace que hace un trabajo decente: http://code.google.com/p/fracture/source/browse/trunk/Squared/TaskLib/ . Sin embargo, si comienza a jugar con usted mismo, notará que realmente necesita soporte de idiomas si desea hacer todas las cosas interesantes, que es exactamente lo que hizo Microsoft.
fuente
Vea este violín https://dotnetfiddle.net/VhZdLU (y mejórelo si es posible) para ejecutar una aplicación de consola simple que muestra los usos de Task, Task.WaitAll (), asíncrono y espera operadores en el mismo programa.
Este violín debería borrar el concepto del ciclo de ejecución.
Aquí está el código de ejemplo
Seguimiento procedente de la ventana de salida:
fuente
fuente
En un nivel superior:
1) La palabra clave asíncrona permite esperar y eso es todo lo que hace. La palabra clave asincrónica no ejecuta el método en un hilo separado. El método f async de inicio se ejecuta sincrónicamente hasta que llegue a esperar en una tarea que requiere mucho tiempo.
2) Puede esperar un método que devuelva Tarea o Tarea de tipo T. No puede esperar un método vacío asíncrono.
3) En el momento en que el hilo principal se encuentra en espera de una tarea que requiere mucho tiempo o cuando se inicia el trabajo real, el hilo principal vuelve al llamador del método actual.
4) Si el hilo principal ve aguardar en una tarea que aún se está ejecutando, no la espera y vuelve al llamador del método actual. De esta manera, la aplicación sigue siendo receptiva.
5) Aguardar en la tarea de procesamiento, ahora se ejecutará en un hilo separado del grupo de hilos.
6) Cuando se completa esta tarea de espera, todo el código a continuación será ejecutado por el hilo separado
A continuación se muestra el código de muestra. Ejecútelo y verifique la identificación del hilo
fuente
La manera en que yo entiendo que es también, debe haber un tercer mandato añadido a la mezcla:
Task
.Async
es solo un calificador que pones en tu método para decir que es un método asincrónico.Task
Es el retorno de laasync
función. Se ejecuta de forma asincrónica.Eres
await
una tarea. Cuando la ejecución del código llega a esta línea, el control salta de nuevo a la persona que llama de su función original circundante.Si por el contrario, se asigna el retorno de una
async
función (por ejemploTask
) a una variable, cuando la ejecución de código llega a esta línea, simplemente continúa más allá de esa línea en la función que rodea , mientras que lasTask
ejecuta de forma asíncrona.fuente
Este artículo MDSN: Programación asincrónica con asíncrono y espera (C #) lo explica explícitamente:
fuente
En el siguiente código, el método HttpClient GetByteArrayAsync devuelve una tarea, getContentsTask. La tarea es una promesa de producir la matriz de bytes real cuando se completa la tarea. El operador de espera se aplica a getContentsTask para suspender la ejecución en SumPageSizesAsync hasta que se complete getContentsTask. Mientras tanto, el control se devuelve a la persona que llama de SumPageSizesAsync. Cuando getContentsTask finaliza, la expresión de espera se evalúa como una matriz de bytes.
fuente
A continuación se muestra el código que lee el archivo de Excel abriendo el cuadro de diálogo y luego usa asíncrono y espera para ejecutar de forma asíncrona el código que lee una a una línea de Excel y se une a la cuadrícula
fuente
Las respuestas aquí son útiles como una guía general sobre wait / async. También contienen algunos detalles acerca de cómo se espera / async está conectado. Me gustaría compartir con ustedes alguna experiencia práctica que deben saber antes de usar este patrón de diseño.
El término "esperar" es literal, por lo que cualquier subproceso en el que lo llame esperará el resultado del método antes de continuar. En primer plano , esto es un desastre . El hilo de primer plano conlleva la carga de construir su aplicación, incluidas las vistas, los modelos de vista, las animaciones iniciales y cualquier otra cosa que haya bloqueado con esos elementos. Entonces, cuando espera el hilo de primer plano, detiene la aplicación. El usuario espera y espera cuando nada parece suceder. Esto proporciona una experiencia de usuario negativa.
Ciertamente puede esperar un hilo de fondo usando una variedad de medios:
El código completo para estos comentarios está en https://github.com/marcusts/xamarin-forms-annoyances . Vea la solución llamada AwaitAsyncAntipattern.sln.
El sitio de GitHub también proporciona enlaces a una discusión más detallada sobre este tema.
fuente
async / await
es el azúcar sintáctico para devoluciones de llamada, no tiene nada que ver con el enhebrado. msdn.microsoft.com/en-us/magazine/hh456401.aspx Es para el código no vinculado a la CPU, por ejemplo, esperando la entrada o un retraso.Task.Run
solo debe usarse para código enlazado a la CPU blog.stephencleary.com/2013/10/…The term "await" is literal, so whatever thread you call it on will wait for the result of the method before continuing.
Esto no es cierto, tal vez te refieres a Task.Wait ()? Cuando lo usaawait
, establece el resto del método como una continuación que se ejecutará cuando se complete lo que esperaba. Sale del método en el que lo usó, por lo que la persona que llama puede continuar. Luego, cuando la línea esperada está realmente completa, finaliza el resto de ese método en algún subproceso (generalmente un subproceso de trabajo).async/await
se trata de liberar .NET Threads. Cuando realizaawait
una operación verdaderamente asíncrona (como File.WriteAsync de .NET), suspende el resto del método que utilizóawait
, para que la persona que llama pueda continuar y potencialmente terminar su propósito. No hay bloqueo de subprocesos o espera de laawait
operación -ed Cuandoawait
se completa la operación que editó, el resto delasync/await
método se coloca en un hilo y se ejecuta (similar a una idea de devolución de llamada).