Graham
Graham

Reputation: 53

Check IsCompleted from a void method with no return possible

I'm trying to get my head around async and await i have been trying to implement it in some code of mine, what I have done so far:

Code:

        public async Task ExcecuteMacroCode(string _macroModeToUse, string[] _macroCode, string _site, Project _project)
        {
            try {
                string macroSelected = _macroModeToUse == "-[REG]" ? "-[REG]" : "-[LAP]";
                if (_macroModeToUse == macroSelected)
                {
                    foreach (string _macroCodeFile in _macroCode)
                    {
                        string[] code = _macroCodeFile.Split('|');

                        switch (code[0])
                        {
                            case "RJ_U":
                                string cleanUrl = code[1].Replace("{HOSTNAME}", _site);
                                browser.Load(cleanUrl);
                                panelBrowserMain.Controls.Add(browser);
                                browser.Dock = DockStyle.Fill;
                                browserMain.Text = cleanUrl;
                                browser.AddressChanged += Browser_AddressChanged;
                                break;
                            case "RJ_I":
                                //await Task.Run(() => {
                                //    return browser.ExecuteScriptAsyncWhenPageLoaded(GetAndReplaceMacro(code[1], _project));
                                //});
                                browser.ExecuteScriptAsyncWhenPageLoaded(GetAndReplaceMacro(code[1], _project));
                                break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Helpers.DebugLogging($"[{DateTime.Now}]-[{ex}]");
            }
        }

        public async Task InitializeChromeBrowserAsync(ChromiumWebBrowser browser, string _macroModeToUse, string[] _macroCode, string _site, int _sitesCount, Project _project, Func<string, Tuple<string, string, string>> getUserPassEmail)
        {
            try
            {
                Task newTask = await ExcecuteMacroCode(_macroModeToUse, _macroCode, _site, _project);
                if (newTask.IsCompleted)
                {
                    this.Close();
                }
            }
            catch (Exception ex)
            {
                Helpers.DebugLogging($"[{DateTime.Now}]-[{ex}]");
            }
        }

The way i have set it up just now i'm getting the error Cannot implicitly convert type 'void' to 'System.Threading.Tasks.Task' from my understanding it's because the method await ExcecuteMacroCode is not returning anything (which is right, i don't need anything returned really)

Is there a way i can still make sure the Task is completed so i can use the newTask.IsCompleted part, i'm not even sure i have set the code up correctly any help would be appreciated.

Upvotes: 1

Views: 74

Answers (1)

dglozano
dglozano

Reputation: 6607

You don't need to manually check if an awaited Task is completed or not. That's already done by the await operator.

The error is that this call await _wellboreService.CreateWellboreSectionAsync(wellboreSection, CurrentUser) is returning void, and you are trying to assign it to Task newTask.

When you await a task, the method is suspended and control is given to the parent caller until the Task is completed, and then it automatically resumes. After the await statement you know that the Task has, in fact, been completed because if not you wouldn't have reached that line in the execution. So there is no need for manually checking the IsCompleted property of the Task.

You could rewrite your code like this:

try
{
    await ExcecuteMacroCode(_macroModeToUse, _macroCode, _site, _project);
    this.Close();
}
catch (Exception ex)
{
    Helpers.DebugLogging($"[{DateTime.Now}]-[{ex}]");
}

You should check the official documentation. for more clarifiation and examples such as this one:

public async Task<int> GetUrlContentLengthAsync()
{
    var client = new HttpClient();

    Task<string> getStringTask =
        client.GetStringAsync("https://learn.microsoft.com/dotnet");

    DoIndependentWork();

    string contents = await getStringTask;

    return contents.Length;
}

void DoIndependentWork()
{
    Console.WriteLine("Working...");
}

Pay close attention to the await operator. It suspends GetUrlContentLengthAsync:

  1. GetUrlContentLengthAsync can't continue until getStringTask is complete.
  2. Meanwhile, control returns to the caller of GetUrlContentLengthAsync.
  3. Control resumes here when getStringTask is complete.
  4. The await operator then retrieves the string result from getStringTask.

Upvotes: 3

Related Questions