I'm attempting to chain together a few async methods I've created and I believe there is some fundamental misunderstanding on my part about how this works
Here's a representation of my code:
public async Task<bool> LoadFoo()
{
return await Foo.ReadAsync("bar").ContinueWith((bar) =>
{
Foo.ReadAsync("baz").ContinueWith((baz) =>
{
Foo.ReadAsync("qux").ContinueWith((qux) =>
{
return true;
});
return true;
});
return true;
});
}
public void LoadEverything()
{
LoadFoo().ContinueWith((blah) =>
{
OtherLoadMethod();
});
}
Now I was expecting when LoadEverything()
was called that all of the ReadAsync
methods in LoadFoo ("bar", "baz" and "qux")
would run and complete, and after they all completed then the .ContinueWith
in LoadEverything
would run so that OtherLoadMethod()
wouldn't execute until the "bar", "baz" and "qux" ReadAsync
methods finished.
What I am actually seeing is that LoadFoo
gets called and then OtherLoadMethod
starts to run before getting to the final completion in LoadFoo
(the ContinueWith
of the "qux" ReadAsync
).
Can someone help clear up my misunderstanding here? Why wouldn't the execution of OtherLoadMethod
wait until ReadAsync("qux")
finishes and returns true?
Why wouldn't execution of OtherLoadMethod wait until ReadAsync("qux") finishes and returns true?
Because that's how await
works. The continuations you register are just that: continuations. They are not executed synchronously in the current method. You are telling the framework that when the current task completes, the continuation should be executed. The Task
object returned by ContinueWith()
allows you to observe the completion if and when it happens. There would be no need to even return a Task
object, if the ContinueWith()
method blocked until the continuation was executed.
Likewise, the Task<bool>
returned by your LoadFoo()
method represents the overall completion of the method, including the await...ContinueWith()
that you're returning. The method returns prior to completion of the continuation, and callers are expected to use the returned task if they need to wait for the continuation to complete.
All that said, I don't understand why you're using ContinueWith()
in the first place. You obviously have access to await
, which is the modern, idiomatic way to handle continuations. IMHO, your code should look something like this (it's not clear why you're returning Task<bool>
instead of Task
, since the return value is only ever true
, but I assume you can figure that part out yourself):
public async Task<bool> LoadFoo()
{
await Foo.ReadAsync("bar");
await Foo.ReadAsync("baz");
await Foo.ReadAsync("qux");
return true;
}
public async Task LoadEverything()
{
await LoadFoo();
await OtherLoadMethod();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With