maxspan
maxspan

Reputation: 14177

Using Func delegate with Async method

I am trying to use Func with Async Method. And I am getting an error.

Cannot convert async lambda expression to delegate type 'Func<HttpResponseMesage>'. An async lambda expression may return void, Task or Task<T>, none of which are convertible to 'Func<HttpResponseMesage>'.

below is my Code:

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

Upvotes: 116

Views: 156878

Answers (5)

Adel Mourad
Adel Mourad

Reputation: 1545

            Transaction transactionInDb = await new Func<Task<Transaction>>(async () =>
            {
                  return await _repo.Transactions.FirstOrDefaultAsync();
            }).Invoke();

Upvotes: -2

Zohar Chiprut
Zohar Chiprut

Reputation: 908

Inside the Func run the task, wait for it and check for exception, then return the result.

Func<HttpResponseMessage> myFun = () => 
{
   var t = Task.Run(async () => await myTask);
   t.Wait();
   if (t.IsFaulted)
      throw t.Exception;
   return t.Result;
};

Upvotes: -2

spender
spender

Reputation: 120508

As the error says, async methods return Task,Task<T> or void. So to get this to work you can:

Func<Task<HttpResponseMessage>> myFun = async () => await myTask;

Upvotes: 162

Johnathon Sullinger
Johnathon Sullinger

Reputation: 7414

The path I usually take is to have the Main method invoke a Run() method that returns a Task, and .Wait() on the Task to complete.

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

This allows the rest of your Console app to run with full async/await support. Since there isn't any UI thread in a console app, you don't run the risk of deadlocking with the usage of .Wait().

Upvotes: 3

Linh Tuan
Linh Tuan

Reputation: 458

Code fix such as:

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

Upvotes: 2

Related Questions