-2

I do not understand when I read the Microsoft documents about async and await working, as it says

Async methods are intended to be non-blocking operations. An await expression in an async method doesn’t block the current thread while the awaited task is running. Instead, the expression signs up the rest of the method as a continuation and returns control to the caller of the async method.

so consider my code:

public  Form1()
{
    InitializeComponent();
    AsyncTest();
    Test(1);
}

private async void AsyncTest()
{
    HttpClient client = new HttpClient();
    var ss =  TT(2);

    var s = await ss;

    for (int i = 0; i < 10; i++)
    {
        //loop
    }
}

private async Task<int> TT(int i)
{
    while (true)
    {
        if (i  > 1000000000)
            break;
        i++;
     }

     return  i;
    }
}

when ever I call AsyncTest(), it just waits behind TT method as it specified with await key, but what does it mean it return control to the main caller?? it is not been returned to the form1, if TT is an infinite loop it just remains forever. thanks

Azzurro94
  • 479
  • 1
  • 7
  • 19
  • 2
    When you compile this code, you get a compiler warning stating that `TT` does not contain an `await` operator and that it will run synchronously. I would suggest you to research based on that warning and it will be clearer what's happening – Camilo Terevinto Jul 22 '18 at 14:33
  • Your for-loop is CPU intensive, not a good stand-in for async I/O. – bommelding Jul 23 '18 at 14:52

1 Answers1

0

It seems to me you are a newbee to async-await. You violate several rules about how to use async-await.

To make a function async do the following:

  • Declare the function async
  • Return Task<TResult> instead of TResult; return Task instead of void
  • ONLY EXCEPTION: event handlers return void instead of Task
  • there should be one await inside your async function. Your compiler will warn you if you omit this.
  • Make sure that all async functions that you call are awaited for before you return

Guideline: let async be a suffix to your async functions. This allows you to create a sync and an async function that do the same: void MyTest() and Task MyTestAsync()

Following these rules, you can't call an async function from within a constructor. As you are using Winforms your code could be like this:

public  Form1()
{
    InitializeComponent();
}

public async void OnButton1_Clicked(object sender, ...)
{   // because this is an event handler the return value is void

    // Start the first test and await until ready
    await TestAsync();

    // Start the second test and await until ready:
    int i = await TestAsync(1);
}

If you call an async function you know that somewhere inside this function is an await. If you have meaningful things to do while the inner function is awaiting, do not await yet. Do your useful things after the call and await the returned Task as soon as you need the result:

public async void OnButton2_Clicked(object sender, ...)
{   
    // Start a test, but don't await yet
    var task1 = TestAsync(1);

    // if here, function TestAsync is awaiting somewhere
    // it is not finished yet, so you can't use the result of it
    // But you can do Something else:
    DoSomethingElse();

    // if here you really need the result of TestAsync, await for it
    int i = await task1;

    // if here you know that TestAsync is finished, i has the proper return value
}

You don't have to start and await the tasks one by one, you can start several tasks and await for them as soon as you need the results:

public async void OnButton3_Clicked(object sender, ...)
{   
    // start several tasks. Don't await yet:
    var task1 = TestAsync(1);
    var task2 = TestAsync(2);
    var task3 = TestAsync(3);

    DoSomethingElse();

    // if here I need the results of all three tasks:
    var myTasks = new Task[] {task1, task2, task3};
    await Task.WhenAll(myTasks);
}

An article that really helped me understanding async-await is this interview with Eric Lippert, where he compares async-await with a cook making breakfast. If a cook has to wait for the water to boil, he doesn't wait idly, but looks around to see if he can do other things. Search somewhere in the middle for async-await.

Another article that helped me following the guidelines of async-await is Async and Await by the ever so helpful Stephen Cleary

Harald Coppoolse
  • 28,834
  • 7
  • 67
  • 116
  • thank you very much,actually I cannot understand the difference between *async* *await* and calling a method in new *thread*! it seems they are both for parallel! – Azzurro94 Jul 28 '18 at 05:44
  • 1
    Apparently you haven't read Eric Lipprt I suggested? Async await: one cook does make the breakfast. Every time he has to wait for water to boil, he looks around to see if he can do something else instead of idly waiting. New thread = hire a cook to do something else while you are waiting idly for the water – Harald Coppoolse Jul 28 '18 at 21:24