简体   繁体   中英

C# - return boolean from Async method

I have Async method which is called inside button_click. Async method runs 3 different void's and each void has It's own error handling. If any error inside those 3 methods occure I want to show that particular error message and stop code inside button_click - which also runs more non-async method and has It's error handling. What I did was this (example):

private void button1_Click(object sender, EventArgs e)
{
    try
    {
       //calling non-async method, if It fails It should show error 
       //inside this event
       Method1();

        if (TestAsync().IsCanceled)
        {
            return;
        }

        MessageBox.Show("Test");
    }
    catch (Exception)
    {
        MessageBox.Show("Async method failed and this message should not be diplayed!");
        throw;
    }
}

public async Task<bool> TestAsync()
{
    bool completed = await Task.Run(() => MethodToComplete());
    return completed;
}

private bool MethodToComplete()
{
    try
    {
        //renaming file, but intentionally fail for test purpose
        Directory.Move("fail_this_method", "fail");
        return true;
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error: " + ex.Message);
        return true;
        throw;
    }
}

The result of this example is - It does display error message from void which is called asynchronously and doesn't show error message from button_click. But It also displays MessageBox.Show("Test"); which shouldn't, code in button_click should stop immidiately if Async fails.

I hope I was clear enough, any help kindly appreaciated !

Before async-await there were other task handling methods, like Task.ContinueWith , Task.IsCanceled etc.

If you plan to use async-await, don't mix them with these older functions.

When you decide to use async-await, stick to the following rules:

  • only declare a function async if it awaits a call to another async function
  • every async function should return Task<TResult> instead of TResult and Task instead of void
  • There is one exception: an async event handler returns void

Furthermore:

  • If you call an async function, but you do not need the result immediately, consider not to await yet, but do the other things. Start awaiting when you need the results of the async function
  • After the await the thread that continues may be a different thread. But it has the same context . This has the effect that you can regard this as if it is the original thread. No need for InvokeRequired , locks and mutexes
  • If you don't need the same context, consider ConfigureAwait(false) after the await. This will speed up the process, with the disadvantage that the continuing thread does not have the user interface context. Therefore you can't access windows Form controls.

Keeping this in mind, you code could be as follows:

private async void button1_Click(object sender, EventArgs e)
{
    // this function must be async because if awaits
    // it is an event hander, hence it returns void instead of Task
    try
    {
        Method1();

        // call TestAsync, if you do not need the result right now,
        // do not await yet
        var myTask = TestAsync();

        // as soon as TestAsync has to await, it continues here:
        // results from TestAsync are not available yet
        DoSomeOtherProcessing();

        // now you need the result from testAsync; await the Task
        bool result = await myTask;
        ProcessResult(result);
    }
    catch (Exception)
    {
       ...
    }
}

A Task that is cancelled, should throw TaskCanceledException . You should not check MyTask.IsCanceled , but catch this exception.

Articles that helped me understanding async-await

  • T his interview with Eric Lippert Search somewhere in the middle for async-await. Eric compares async-await with a cook making dinner. Once he put on the kettle, he does not idly wait for the water to boil, but looks around to see if he can do other things instead, like chopping onions
  • async-await by the ever so helpful Stephen Cleary

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM