Aplicación de terminación de la consola Antes de finalización de llamada asincrónica
-
27-09-2019 - |
Pregunta
Actualmente estoy escribiendo una aplicación de consola de C # que genera un número de URLs que apuntan a diferentes imágenes en una página web y luego descargas como byte arroyos utilizando WebClient.DownloadDataAsync()
.
Mi problema es que una vez que se hizo la primera llamada asincrónica, la aplicación de consola considera que el programa para ser completado y termina antes de la llamada asincrónica puede devolver. Mediante el uso de un Console.Read()
puedo obligar a la consola para permanecer abierto, pero esto no parece ser muy buen diseño. Por otra parte, si los accesos de los usuarios entran en el proceso (mientras la consola está esperando una entrada) el programa termina.
¿Hay una mejor manera de evitar que la consola se cierre mientras yo estoy esperando una llamada asincrónica a cambio?
Editar:. Las llamadas son asíncronas porque yo estoy proporcionando un indicador de estado a través de la consola para el usuario, mientras que las descargas tienen lugar
Solución
Sí. Utilizar un ManualResetEvent , y tienen la event.Set()
asíncrono llamada de devolución de llamada . Si los bloques de rutina principal en event.WaitOne()
, que no saldrá hasta que se complete el código asíncrono.
El pseudo-código básico se vería así:
static ManualResetEvent resetEvent = new ManualResetEvent(false);
static void Main()
{
CallAsyncMethod();
resetEvent.WaitOne(); // Blocks until "set"
}
void DownloadDataCallback()
{
// Do your processing on completion...
resetEvent.Set(); // Allow the program to exit
}
Otros consejos
Otra opción es simplemente llamar a un método asíncrono principal y esperar en la tarea de regresar.
static void Main(string[] args)
{
MainAsync(args).Wait();
}
static async Task MainAsync(string[] args)
{
// .. code goes here
}
Desde .NET 4.5 ahora se puede llamar GetAwaiter().GetResult()
static void Main(string[] args)
{
MainAsync(args).GetAwaiter().GetResult();
}
¿Cuál es la diferencia entre .Wait () vs. GetAwaiter (). GetResult ()?
Si eso es todo lo que hace la aplicación, sugeriría dejando de lado la llamada asincrónica; usted específicamente desea la aplicación para 'colgar' hasta que la descarga se ha completado, así que usar una operación asincrónica es contrario a lo que usted quiere aquí, sobre todo en una aplicación de consola.
Hay que señalar que en C # 7.1 Main
ahora se puede marcar como async
.
static async Task Main()
{
await LongRunningOperation();
}