it-swarm.com.de

async bei der Konsolen-App in C #?

Ich habe diesen einfachen Code:

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;
}

Toll. dies kompiliert.

Nehmen wir an, ich habe eine Konsolen-App und möchte den obigen Code ausführen (Aufruf von SumTwoOperationsAsync())

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

Aber ich habe gelesen, dass ich (wenn ich sync verwende) die ganze Zeit synchronisieren muss up und down :

Frage : Bedeutet das also, dass meine Main -Funktion als async markiert werden sollte?

Nun, es kann kann nicht sein, weil ein Kompilierungsfehler vorliegt:

ein Einstiegspunkt kann nicht mit dem Modifikator 'async' markiert werden

Wenn ich das asynchrone Zeug verstehe, wird der Thread die Funktion Main eingeben ----> SumTwoOperationsAsync ----> wird beide Funktionen aufrufen und wird raus sein. aber bis zum SumTwoOperationsAsync

Was vermisse ich ?

166
Royi Namir

In den meisten Projekttypen endet Ihr async "up" und "down" bei async void Eventhandler oder Rückgabe eines Task an Ihr Framework.

Konsolen-Apps unterstützen dies jedoch nicht.

Sie können entweder nur ein Wait für die zurückgegebene Aufgabe ausführen:

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

static async Task MainAsync()
{
  ...
}

oder du kannst benutze deinen eigenen Kontext wie den, den ich geschrieben habe :

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

static async Task MainAsync()
{
  ...
}

Weitere Informationen zu async Console-Apps finden Sie unter in meinem Blog .

279
Stephen Cleary

Hier ist der einfachste Weg, dies zu tun

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

static async Task MainAsync(string[] args)
{
    await ...
}
90

Als schnelle und zielgerichtete Lösung:

Task.Result

Sowohl Task.Result als auch Task.Wait ermöglichen keine Verbesserung der Skalierbarkeit bei Verwendung mit E/A, da der aufrufende Thread blockiert bleibt und auf das Ende der E/A wartet.

Wenn Sie .Result für eine unvollständige Aufgabe aufrufen, muss der Thread, der die Methode ausführt, warten, bis die Aufgabe abgeschlossen ist. Dadurch wird der Thread daran gehindert, in der Zwischenzeit andere nützliche Aufgaben auszuführen. Dies negiert den Vorteil der Asynchronität der Aufgabe.

notasync

3
Alberto

Meine Lösung. Der JSONServer ist eine Klasse, die ich geschrieben habe, um einen HttpListener-Server in einem Konsolenfenster auszuführen.

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);

    }
}
1
Richard Keene