c# .net-4.5 async-await c#-5.0

asincrónico en la aplicación de la consola en C#?



.net-4.5 async-await (4)

Tengo este código simple:

public static async Task<int> SumTwoOperationsAsync() { var firstTask = GetOperationOneAsync(); var secondTask = GetOperationTwoAsync(); return await firstTask + await secondTask; } private async Task<int> GetOperationOneAsync() { await Task.Delay(500); // Just to simulate an operation taking time return 10; } private async Task<int> GetOperationTwoAsync() { await Task.Delay(100); // Just to simulate an operation taking time return 5; }

Estupendo. esto compila

Pero digamos que tengo una aplicación de consola y quiero ejecutar el código anterior (llamando a SumTwoOperationsAsync() )

static void Main(string[] args) { SumTwoOperationsAsync(); }

Pero lo he leído (cuando uso la sync ) Tengo que sincronizar todo el camino hacia arriba y hacia abajo :

Pregunta : Entonces, ¿esto significa que mi función Main debe estar marcada como async ?

Bueno, no puede ser porque hay un error de compilación:

un punto de entrada no se puede marcar con el modificador ''async''

Si entiendo las cosas de asincronización, el hilo entrará en la función Main ----> SumTwoOperationsAsync ----> llamará a ambas funciones y saldrá. pero hasta el SumTwoOperationsAsync

Qué me estoy perdiendo ?


Como una solución rápida y de gran alcance:

Task.Result

Tanto Task.Result como Task.Wait no permitirán mejorar la escalabilidad cuando se utilizan con E / S, ya que harán que el hilo de llamada permanezca bloqueado esperando a que termine la E / S.

Cuando llamas .Result en una Tarea incompleta, el hilo que ejecuta el método tiene que sentarse y esperar a que la tarea se complete, lo que impide que el hilo haga otro trabajo útil mientras tanto. Esto niega el beneficio de la naturaleza asincrónica de la tarea.

notasync


En la mayoría de los tipos de proyectos, su async "arriba" y "abajo" finalizará en un controlador de eventos async void o devolverá una Task a su marco de trabajo.

Sin embargo, las aplicaciones de la consola no son compatibles.

Puede hacer una Wait en la tarea devuelta:

static void Main() { MainAsync().Wait(); // or, if you want to avoid exceptions being wrapped into AggregateException: // MainAsync().GetAwaiter().GetResult(); } static async Task MainAsync() { ... }

o puedes usar tu propio contexto como el que escribí :

static void Main() { AsyncContext.Run(() => MainAsync()); } static async Task MainAsync() { ... }

Más información para las aplicaciones de la consola async está en mi blog .


Esta es la forma más simple de hacer esto

static void Main(string[] args) { Task t = MainAsync(args); t.Wait(); } static async Task MainAsync(string[] args) { await ... }


Mi solución. JSONServer es una clase que escribí para ejecutar un servidor HttpListener en una ventana de consola.

class Program { public static JSONServer srv = null; static void Main(string[] args) { Console.WriteLine("NLPS Core Server"); srv = new JSONServer(100); srv.Start(); InputLoopProcessor(); while(srv.IsRunning) { Thread.Sleep(250); } } private static async Task InputLoopProcessor() { string line = ""; Console.WriteLine("Core NLPS Server: Started on port 8080. " + DateTime.Now); while(line != "quit") { Console.Write(": "); line = Console.ReadLine().ToLower(); Console.WriteLine(line); if(line == "?" || line == "help") { Console.WriteLine("Core NLPS Server Help"); Console.WriteLine(" ? or help: Show this help."); Console.WriteLine(" quit: Stop the server."); } } srv.Stop(); Console.WriteLine("Core Processor done at " + DateTime.Now); } }