-4

I am not familiar with threading in .NET.

I have an ansync method MyTest:

public async Task MyTest() {
    using (HttpClient httpClient = new HttpClient()) {
        httpClient.BaseAddress = new Uri(_uri);

        var response = await httpClient.GetAsync("API/GetData");

        if(response!=null && response.IsSuccessStatusCode) {
            var json = await response.Content.ReadAsStringAsync();
            return JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
        }
    }
}

The problem that I am running into is calling the method to get the results (Dictionary).

When I step though my code I am seeing the IsCompleted is done before the results come back from my rest call.

How do I properly use threading in this case?

My method to call the async method.

public void GetTestData()
{
    try
    {                
        ARestService rest = new ARestService();
        Task tsk = new Task(rest.MyTest);
        if (tsk.IsCompleted)
        {
            var tst = "Done?";
        }
    }
    catch(Exception ex)
    {
        string a = ex.Message;
    }
}
John Doe
  • 3,053
  • 17
  • 48
  • 75
  • Please, feel free to read some tutorials on async/await instead of fumbling your way through the dark. – Glorin Oakenfoot Nov 03 '16 at 15:06
  • 1
    Possible duplicate of [How to call asynchronous method from synchronous method in C#?](http://stackoverflow.com/questions/9343594/how-to-call-asynchronous-method-from-synchronous-method-in-c) – meJustAndrew Nov 03 '16 at 15:07
  • Just call it and await the result. Or await it directly. The method is asynchronous because **.ReadAsStringAsync** is already asynchronous and runs in the background. The method returns an already running task that you just have to await – Panagiotis Kanavos Nov 03 '16 at 15:07
  • What you want is to `await` it if you want it to be asynchronous (the thread is not blocked while waiting on IO) or you can call `Result` or `Wait` on the task to synchronously block the thread. – juharr Nov 03 '16 at 15:08
  • *NOT a duplicate*, that question is about `async void`, a very special case. – Panagiotis Kanavos Nov 03 '16 at 15:09
  • @PanagiotisKanavos - I think the 2nd answer still applies though (http://stackoverflow.com/a/25097498/1260204). – Igor Nov 03 '16 at 15:12

1 Answers1

-1

If you can turn your GetTestData method into an async method simply do this.

public async Task GetTestData()
{
    try
    {                
        ARestService rest = new ARestService();
        await rest.MyTest();
        var tst = "Done?";
    }
    catch(Exception ex)
    {
        string a = ex.Message;
    }
}

You should also define that your method returns a Task<Dictionary<string, string>> to receive the result of your rest service call, with the following statement.

Dictionary<string, string> dict = await rest.MyTest();

If not, have a look at some workarounds, like using GetAwaiter().GetResult() but as explained in this question Is .GetAwaiter().GetResult(); safe for general use? it can cause some problems, so the best option is to make your calling code async too.

Community
  • 1
  • 1
jorgonor
  • 1,679
  • 10
  • 16
  • 1
    First, you are hiding possible exepctions. Second, the other question is about `async void` *only*. You can just call `.Result` on the return value if you want to block synchronously – Panagiotis Kanavos Nov 03 '16 at 15:10
  • Good point! I realized the link is not exactly the same scenario. I have seldom used the `GetAwaiter().GetResult()` workaround only in console applications. – jorgonor Nov 03 '16 at 15:15