Reputation: 866
I have the following
async void A () {
await B();
}
async Task B () {
await Task.Factory.StratNew( ()=> C());
}
async Task C () {
while (true) {
//await Task.Factory.StartNew(()=> {Thread.Sleep(5000);});
Thread.Sleep(5000);
}
}
In the program above, A
never returns because the while loop inside C
. However if I uncomment the line inside C
and KEEP Thread.Sleep(5000)
, A
immediately returns. Could someone explain what is happening in there ?
Upvotes: 1
Views: 137
Reputation: 62268
The main problem is thorouhly described in the article Task.Run vs Task.Factory.StartNew. If you were to change your code like this you would see what you were expecting I think.
async void A()
{
await B();
}
async Task B()
{
// await Task.Factory.StartNew(() => C());
await Task.Run(async () => await C());
// await Task.Run(() => C()); // this would still produce the same effect
}
async Task C()
{
while (true)
{
await Task.Delay(5000);
//Thread.Sleep(5000);
}
}
See also this previous answer by Stephen Cleary. Essentially Task.Factory.StartNew
does not respect the async/await
model and you really should be using Task.Run
with async/await
code. Task.Factory.StartNew
creates and starts a new Task without acually awaiting the results with the exception of when the Task returned is executed synchronously which happened when you removed the await inside of C
.
Upvotes: 3
Reputation: 3319
When you have "await" inside you infinite loop, runtime interrupts infinite loop, yielding execution to outer calls, giving the chance to complete B (and consequently A) then it returns back to infinite loop.
Without the "await" there is no way B (and consequently A) can ever finish, they will "await" forever.
Upvotes: 2