0

I am trying get a string from an async method that returns a string as type Task string

My code:

 class DataScraper
    {
        private static readonly HttpClient client = new HttpClient();
      
       public static async Task<string> getParagraph()
        {
         
            string subject1 = "";
         
            string subject2 = "";
            Dictionary<string, string> parameters = new Dictionary<string, string>()
        {
            { "Subject1", subject1 },
            { "Subject2", subject2 }
        };
            try
            {
                string result = await PostHTTPRequestAsync("http://watchout4snakes.com/wo4snakes/Random/RandomParagraph", parameters);
                return await Task.FromResult(result);
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private static async Task<string> PostHTTPRequestAsync(string url, Dictionary<string, string> data)
        {
            using (HttpContent formContent = new FormUrlEncodedContent(data))
            using (HttpResponseMessage response = await client.PostAsync(url, formContent).ConfigureAwait(false))
            {
                response.EnsureSuccessStatusCode();
                return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            }
        }
    }

When using it in another class like this:

 string s = DataScraper.getParagraph();

I get an error that says:

Cannot implicitly convert type 'System.Threading.Tasks.Task<string>' to 'string'
RyM
  • 169
  • 2
  • 3
  • 10
  • get rid of this line: `return await Task.FromResult(result);` and just do `return result;` – Andy Aug 04 '20 at 20:31
  • @Andy I tried that and it gives me the same error :\ – RyM Aug 04 '20 at 20:32
  • 2
    You also must await any asynchronous calls you make. Thus it should be `string s = await DataScraper.getParagraph()`. And yes, that means that the method that code runs from should also be marked as async, and the method that calls that should be marked as async, all the way up the call stack until you get to the main method or an event handler. – mason Aug 04 '20 at 20:32
  • 1
    You need to use `await` : ` string s = await DataScraper.getParagraph();` – Eldar Aug 04 '20 at 20:32
  • 1
    It is a good practice to add the suffix `Async` to your async methods. So, it should be `getParagraphAsync()`. That way the caller doesn't have to think about it, he/she will know it's async immediatly. – Andy Aug 04 '20 at 20:34
  • Well while we're talking about naming conventions, a method name in C# is traditionally pascal cased, so it'd be either `GetParagraph` or `GetParagraphAsync`. Note that the async suffix is not accepted by everyone, [there is discussion around it](https://docs.particular.net/nservicebus/upgrades/5to6/async-suffix) in various circles. – mason Aug 04 '20 at 20:35

1 Answers1

1

Your getParagraph method has return type of Task<string> as your PostHTTPRequestAsync does, so you can try to handle it the same way using await (as you do in string result = await PostHTTPRequestAsync(...)):

string s = await DataScraper.getParagraph();

Also no need to wrap result into await Task.FromResult, return result should work fine.

Also you can read about more asynchronous programming with async and await in the docs.

Guru Stron
  • 102,774
  • 10
  • 95
  • 132