478 Stimmen

Wie ruft man sicher eine asynchrone Methode in C# auf, ohne await zu verwenden?

Ich habe eine async-Methode, die keine Daten zurückgibt:

public async Task MyAsyncMethod()
{
    // Führe einige Aufgaben asynchron aus, gebe keine Daten zurück
}

Ich rufe dies von einer anderen Methode aus auf, die einige Daten zurückgibt:

public string GetStringData()
{
    MyAsyncMethod(); // Dies erzeugt eine Warnung und unterdrückt Ausnahmen
    return "Hallo Welt";
}

Wenn MyAsyncMethod() aufgerufen wird, ohne darauf zu warten, wird in Visual Studio eine "Da dieser Aufruf nicht abgewartet wird, wird die aktuelle Methode weiterhin ausgeführt, bevor der Aufruf abgeschlossen ist"-Warnung angezeigt. Auf der Seite für diese Warnung heißt es:

Sie sollten die Warnung nur unterdrücken, wenn Sie sicher sind, dass Sie nicht auf das Abschließen des asynchronen Aufrufs warten möchten und dass die aufgerufene Methode keine Ausnahmen auslöst.

Ich bin mir sicher, dass ich nicht auf das Abschließen des Aufrufs warten möchte; Ich brauche es nicht oder habe keine Zeit dafür. Aber der Aufruf könnte Ausnahmen auslösen.

I ch bin ein paar Mal auf dieses Problem gestoßen, und ich bin sicher, dass es ein häufiges Problem ist, das eine gemeinsame Lösung haben muss.

Wie rufe ich sicher eine async-Methode auf, ohne auf das Ergebnis zu warten?

Aktualisierung:

Für Personen, die vorschlagen, dass ich einfach auf das Ergebnis warten soll, handelt es sich hier um Code, der auf eine Webanforderung auf unserem Webservice (ASP.NET Web-API) reagiert. Das Warten in einem UI-Kontext hält den UI-Thread frei, aber das Warten in einem Webanforderungsaufruf würde auf das Beenden des Tasks warten, bevor auf die Anforderung geantwortet wird, was die Antwortzeiten ohne Grund erhöht.

-2voto

Miguel Punkte 68

Vielleicht bin ich zu naiv, aber könntest du ein Ereignis erstellen, das ausgelöst wird, wenn GetStringData() aufgerufen wird, und einen EventHandler anhängen, der die asynchrone Methode aufruft und darauf wartet?

So etwas wie:

public event EventHandler FireAsync;

public string GetStringData()
{
   FireAsync?.Invoke(this, EventArgs.Empty);
   return "hello world";
}

public async void HandleFireAsync(object sender, EventArgs e)
{
   await MyAsyncMethod();
}

Und irgendwo im Code das Ereignis anhängen und abhängen:

FireAsync += HandleFireAsync;

(...)

FireAsync -= HandleFireAsync;

Weiß nicht, ob das irgendwie gegen das Muster ist (falls ja, lass es mich bitte wissen), aber es fängt die Ausnahmen ab und kehrt schnell von GetStringData() zurück.

-3voto

Ernesto Garcia Punkte 3

Die Lösung besteht darin, den HttpClient in einer anderen Ausführungsaufgabe ohne Synchronisierungskontext zu starten:

var submit = httpClient.PostAsync(uri, new StringContent(body, Encoding.UTF8,"application/json"));
var t = Task.Run(() => submit.ConfigureAwait(false));
await t.ConfigureAwait(false);

-3voto

Es ist einfach, rufen Sie einfach asyncMethod().Result auf, um ohne await zu rufen. Unten ist der Beispielcode und hier ist das Fiddle

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {   
        var asyncDemo = new AsyncDemo();
        asyncDemo.TestMethod1Void().Wait();
        var result = asyncDemo.TestMethod1().Result;
        Console.WriteLine(result);
    }
}

public class AsyncDemo {

    public async Task TestMethod1()
    {
        Thread.Sleep(1000);
        return  "Von Async Methode";        
    }

    public async Task TestMethod1Void()
    {
        Thread.Sleep(1000);
        Console.WriteLine("Async Void Methode");     
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X