1
    class MyHttpClientClass
    {
        public async static string Getrequest(string url, string port)
        {
            using (HttpClient client = new HttpClient())
            {
                using (HttpResponseMessage response = await client.GetAsync("http://" + url + ":" + port + "/"))
                {
                    using (HttpContent content = response.Content)
                    {
                        return await content.ReadAsStringAsync();
                    }
                }
            }
        }
    }

This source code gives me a compile-time error:

The return type of an async method must be void, Task, or Task<T>

How can I return a string from this method without using out or ref?
I also want to get rid of async/await pattern.

5
  • 2
    You really don't want to get rid of async/await. You shouldn't be creating a new HttpClient each time either, it's thread-safe and meant to be reused. Reusing it means you don't have to perform DNS resolution for every request too, which can really speed up performance* Commented Mar 5, 2020 at 12:03
  • This entire method could be replaced with _httpClient.GetStringAsync(someUrl) Commented Mar 5, 2020 at 12:04
  • 1
    As a side note, HttpClient is intended to be instantiated once and re-used throughout the life of an application. Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads. (citation) Commented Mar 5, 2020 at 12:17
  • The problem with socket exhaustion is explained in You're using HttpClient wrong and it's destabilizing your software and You're still using HttpClient wrong Commented Mar 5, 2020 at 12:20
  • The solution isn't to avoid HttpClient. You can use HttpClientFactory to get pooled sockets, periodic recycling to handle DNS changes and integrate with Polly to implement retry strategies Commented Mar 5, 2020 at 12:21

3 Answers 3

11

Change it to return a Task<string>:

public async static Task<string> Getrequest(string url, string port)
Sign up to request clarification or add additional context in comments.

7 Comments

I want to make it look like an ordinary function. Rather than Task<string>, I want to return string.
@user366312 You can't do that as you've opted to use the async/await pattern. It has to return either void, a Task or a Task<> type.
How can I rewrite this to get rid of async/await?
@user366312 - You'll need to use an http client class that provides synchronous methods and use this instead. HttpClient is aimed at making async requests.
@user366312 there are more problems with Getrequest too. HttpClient is thread-safe and meant to be reused. This can save you the up to 15 seconds needed for DNS resolution. The OS itself pools and reuses sockets, so creating a new HttpClient every time a) can add up to 15s of delay and b) can lead to socket starvation
|
1

An async method can only return the following types:

  • void (not really a return type, used to indicate you do not want to be notified of the completion of underlying task, only useful when attaching an async event handler since delegate type is frozen.)
  • Task (method does not return a value, sync version would have void return type.)
  • Task<T> (method returns a task whose result is of type T, sync version would have return type T.)
  • ValueTask (method does not return a value, uses ValueTask for performance, sync version would have void return type).
  • ValueTask<T> (method returns a task alike of type T, uses ValueTask for performance, sync version would have return type T.)
  • IAsyncEnumerable<T> (method returns an async stream of T, new feature introduced in C# 8.0.)

The error message you are seeing is the compiler trying to tell you that you do not meet the expectation. The error message itself is incomplete, even the documentation on async methods on learn.microsoft.com does not mention the last case. Here's the github issue to track that change.

Comments

1

If you dont want to async/await, you can use this

    public static string Getrequest(string url, string port)
    {
        using (var client = new WebClient())
        {
            return client.DownloadString("http://" + url + ":" + port + "/");
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.