我试图将我创建的一些异步方法联系在一起,我相信对于我的工作原理存在一些根本性的误解
这是我的代码的代表:
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();
});
}
现在我希望在LoadEverything()
被调用时,ReadAsync
中的所有LoadFoo ("bar", "baz" and "qux")
方法都会运行并完成,并且在它们全部完成后,.ContinueWith
在{ {1}}会运行,以便LoadEverything
不会执行,直到&#34;&#34;,&#34; baz&#34;和&#34; qux&#34; OtherLoadMethod()
方法已完成。
我实际看到的是ReadAsync
被调用,然后LoadFoo
开始运行,然后才开始OtherLoadMethod
LoadFoo
的{{1}} 34; qux&#34; ContinueWith
)。
有人可以帮我解决我的误会吗?为什么ReadAsync
的执行不会等到OtherLoadMethod
完成并返回true?
答案 0 :(得分:9)
为什么执行OtherLoadMethod会等到ReadAsync(“qux”)结束并返回true?
因为这是await
的工作方式。您注册的延续只是: continuations 。它们不是在当前方法中同步执行的。您告诉框架当前任务完成时,应该执行继续。 Task
返回的ContinueWith()
对象允许您在发生时查看完成情况。如果Task
方法被阻塞直到执行继续,则无需返回ContinueWith()
个对象。
同样,Task<bool>
方法返回的LoadFoo()
表示该方法的整体完成情况,包括您要返回的await...ContinueWith()
。该方法在完成延续之前返回,如果需要等待继续完成,则调用者应使用返回的任务。
所有这一切,我不明白为什么你首先使用ContinueWith()
。您显然可以访问await
,这是处理延续的现代惯用方法。恕我直言,你的代码看起来应该是这样的(不清楚你为什么要返回Task<bool>
而不是Task
,因为返回值只是true
,但我想你可以想象那部分你自己):
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();
}
答案 1 :(得分:-1)
您也可以使用Unwrap
:
public async Task<bool> LoadFoo()
{
await Foo.ReadAsync("bar")
.ContinueWith(_ => Foo.ReadAsync("baz")).Unwrap()
.ContinueWith(_ => Foo.ReadAsync("qux")).Unwrap();
return true;
}
public async Task LoadEverything()
{
await LoadFoo().ContinueWith(_ => OtherLoadMethod()).Unwrap();
}