Home > Software engineering >  Calling async function in synchronous function doesn't wait for it to finish
Calling async function in synchronous function doesn't wait for it to finish

Time:05-27

I'm trying to call the async function getLatestTag in a synchronous one, but I can't get the program to finish for it to execute before continuing.

public static void checkInstalled()
{
    var t = new Task(getLatestTag);
    t.Start();
    if (623 == tagOutput)
    {
        MessageBox.Show("succes");
    }
    else
    {
        MessageBox.Show("fail");
    }
}

private static async void getLatestTag()
{
    var httpClient = new HttpClient();
    var request = new HttpRequestMessage(HttpMethod.Get, "https://api.github.com/repos/Futminer/miner-download/releases/latest");
    var productValue = new ProductInfoHeaderValue("FutMiner", "1.0");
    request.Headers.UserAgent.Add(productValue);
    var resp = await httpClient.SendAsync(request);
    HttpContent content = resp.Content;
    string data = await content.ReadAsStringAsync();
    dynamic obj = JsonConvert.DeserializeObject(data);
    tagOutput = Convert.ToInt32(obj["tag_name"]);
}

CodePudding user response:

Following Panagiotis Kanavos's advice:

Tasks aren't threads. There's no good reason to call Task.Start in application code. How is checkInstalled called? That method should be asynchronous itself, going all the way to the top-level event handler that started these calls. The event handler should be async void but all the other methods should be async Task. Calling .Wait() will freeze the UI

After making every necessary function async and using await when needed I managed to get everything working the way I wanted

CodePudding user response:

First off, never return void from an async method - rather return a Task instance.

Then, if you're certain that you want to handle the async method in a sync method, to force it to wait for the result you need .Result on it.

So your code should be like this:

public static void checkInstalled()
{
    getLatestTag().Wait();
    
    if (623 == tagOutput)
    {
        MessageBox.Show("succes");
    }
    else
    {
        MessageBox.Show("fail");
    }
}

private static async Task getLatestTag()
{
    var httpClient = new HttpClient();
    var request = new HttpRequestMessage(HttpMethod.Get, "https://api.github.com/repos/Futminer/miner-download/releases/latest");
    var productValue = new ProductInfoHeaderValue("FutMiner", "1.0");
    request.Headers.UserAgent.Add(productValue);
    var resp = await httpClient.SendAsync(request);
    HttpContent content = resp.Content;
    string data = await content.ReadAsStringAsync();
    dynamic obj = JsonConvert.DeserializeObject(data);
    tagOutput = Convert.ToInt32(obj["tag_name"]);
}
  • Related