-4

I'm calling a web service from some C# code. This code looks similar to this:

using (var client = new HttpClient())
{
  var page = "http://en.wikipedia.org/";
  using (var response = await client.GetAsync(page))
  {
    using (var content = response.Content)
    {
      var result = await content.ReadAsStringAsync();
    }
  }
}

I want to execute this code within a utility method. From my understanding, an Action delegate is suited for this. I attempted to do this using the following:

Action action = delegate()
{
  using (var client = new HttpClient())
  {
    var page = "http://en.wikipedia.org/";
    using (var response = await client.GetAsync(page))
    {
      using (var content = response.Content)
      {
        var result = await content.ReadAsStringAsync();
      }
    }
  }
}

When I wrap my web service code in an Action delegate, I receive a compile-time error that says:

The 'await' operator can only be used within an async anonymous method. Consider marking this anonymous method with the 'async' modifier.

My question is, how do I call async code in an Action? It looks like I can't. If I can't is there another way that I can pass a block of code to a utility method for execution? What does that look like?

Thank you!

3
  • 4
    Action action = async delegate() ... Commented Apr 30, 2018 at 17:55
  • Func<Task> action = async () => {/*method body*/} would also work. That way a Task is being returned that can be awaited by the caller of your method. As Action has the return type void I do not believe it can be awaited further up the call stack. Commented Apr 30, 2018 at 17:58
  • 1
    Use a static HttpClient instance; don't create a new one all the time. Commented Apr 30, 2018 at 18:00

1 Answer 1

1

You need to mark your action as async just like you would any method, for example:

Action action = async delegate() 
    //snip

However, this is equivalent to an async void method which is not recommended. Instead you many consider using Func<Task> instead of action:

Func<Task> doStuff = async delegate()
{
  using (var client = new HttpClient())
  {
    var page = "http://en.wikipedia.org/";
    using (var response = await client.GetAsync(page))
    {
      using (var content = response.Content)
      {
        var result = await content.ReadAsStringAsync();
      }
    }
  }
}

Now you can await the result:

await doStuff();
Sign up to request clarification or add additional context in comments.

3 Comments

HttpClient shouldn't be created/disposed for each request.
@xxbbcc Well yes, but that's a different question
Yes, I know, I even hesitated posting the comment. I only did so because people will find your (otherwise good) sample and will just copy & paste without thinking.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.