使用Func委托与Async方法

max*_*pan 48 c# lambda asynchronous

我试图使用Func与异步方法.我收到了一个错误.

无法将异步lambda表达式转换为委托类型'Func<HttpResponseMesage>'.异步lambda表达式可能返回void,Task或者Task<T>都不能转换为'Func<HttpResponseMesage>'.

以下是我的代码:

public async Task<HttpResponseMessage> CallAsyncMethod()
{
    Console.WriteLine("Calling Youtube");
    HttpClient client = new HttpClient();
    var response = await client.GetAsync("https://www.youtube.com/watch?v=_OBlgSz8sSM");
    Console.WriteLine("Got Response from youtube");
    return response;
}

static void Main(string[] args)
{
    Program p = new Program();
    Task<HttpResponseMessage> myTask = p.CallAsyncMethod();
    Func<HttpResponseMessage> myFun =async () => await myTask;
    Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)

spe*_*der 72

正如错误所说,异步方法返回Task,Task<T>void.为了让这个工作,您可以:

Func<Task<HttpResponseMessage>> myFun = async () => await myTask;
Run Code Online (Sandbox Code Playgroud)

  • 请注意,当用户按下某个键时,异步操作可能无法完成,并且"Console.ReadLine()"已完成.应用程序可以在异步操作完成之前终止,除非您在`Task`上明确地"等待". (3认同)

Joh*_*ger 5

我通常采取的路径是让该Main方法调用Run()返回任务的方法,然后.Wait()完成Task

class Program
{
    public static async Task<HttpResponseMessage> CallAsyncMethod()
    {
        Console.WriteLine("Calling Youtube");
        HttpClient client = new HttpClient();
        var response = await client.GetAsync("https://www.youtube.com/watch?v=_OBlgSz8sSM");
        Console.WriteLine("Got Response from youtube");
        return response;
    }

    private static async Task Run()
    {
        HttpResponseMessage response = await CallAsyncMethod();
        Console.ReadLine();
    }

    static void Main(string[] args)
    {
        Run().Wait();
    }
}
Run Code Online (Sandbox Code Playgroud)

这允许控制台应用程序的其余部分在完全异步/等待支持的情况下运行。由于控制台应用程序中没有任何 UI 线程,因此使用.Wait().

  • 您提供的链接适用于 MVC 应用程序,您是正确的。在 C# 7.2 之前,这是您必须在控制台应用程序中执行的操作,否则控制台应用程序会在异步操作完成之前完成执行并关闭。在控制台应用程序中无需担心任何 SyncContext。但是,C# 7.2 允许您的“Main”方法返回异步任务,以便您可以在控制台应用程序中等待。 (4认同)
  • 这将使用 Wait() 阻塞任务,并且它不再是执行异步上下文的正确方法。请阅读另一个问题[此处](/sf/ask/919836641/) (2认同)