TaskCanceledException时不等待 [英] TaskCanceledException when not awaiting
问题描述
我似乎得到一个 TaskCanceledException
每当我返回另一个任务,而不是同步等待它,在之后的最后当你等待。
I seem to be getting a TaskCanceledException
whenever I return another Task synchronously instead of awaiting it, following the guidelines in When at last you await.
public static class Download
{
public static Task<byte[]> FromYouTubeAsync(string videoUri)
{
using (var client = new HttpClient())
{
return FromYouTubeAsync(
() => client
.GetStringAsync(videoUri),
uri => client
.GetByteArrayAsync(uri));
}
}
public async static Task<byte[]> FromYouTubeAsync(
Func<Task<string>> sourceFactory, Func<string, Task<byte[]>> downloadFactory)
{
string source = await // TaskCanceledException here
sourceFactory()
.ConfigureAwait(false);
// find links
return await
downloadFactory(links.First())
.ConfigureAwait(false);
}
}
异常免费code
下面,该方法的签名的第一过载被改变为异步,并且它等待第二过载。出于某种原因,这prevents的 TaskCanceledException
。
public static class Download
{
public async static Task<byte[]> FromYouTubeAsync(string videoUri)
{
using (var client = new HttpClient())
{
return await FromYouTubeAsync(
() => client
.GetStringAsync(videoUri),
uri => client
.GetByteArrayAsync(uri));
}
}
public async static Task<byte[]> FromYouTubeAsync(
Func<Task<string>> sourceFactory, Func<string, Task<byte[]>> downloadFactory)
{
string source = await // No exception!
sourceFactory()
.ConfigureAwait(false);
// find links
return await
downloadFactory(links.First())
.ConfigureAwait(false);
}
}
为什么会这样,我能做些什么来解决这个问题(除了等待方法,浪费了资源在上面的链接说明)?
Why does this happen and what can I do to fix it (besides awaiting the method, which wastes resources as described in the link above)?
推荐答案
不好意思,的链接你贴是关于应用优化的是仅适用如果该方法后,没有它的等待
的。引用帖子:
Sorry, the link you posted is about applying an optimization which is only applicable if the method does nothing after its await
. To quote the post:
在此情况下,然而,我们被交给一个任务重新present在方法的最后一条语句,因此它实际上已经是一个再$整个方法的处理的对$ psentation ...
In this case, however, we’re being handed a task to represent the last statement in the method, and thus it’s in effect already a representation of the entire method’s processing...
在你的榜样,任务做的不的再present在方法的最后一条语句。再看一下:
In your example, the task does not represent the last statement in the method. Look again:
public async static Task<byte[]> FromYouTubeAsync(string videoUri)
{
using (var client = new HttpClient())
{
return await FromYouTubeAsync(...);
}
}
有后出事的 的的等待
:具体而言,客户端的处置
。所以在这个博客中提到的最优化的在这里并不适用的
There's something happening after the await
: specifically, the disposing of client
. So the optimization mentioned in that blog post does not apply here.
这就是为什么你看到一个异常,如果您尝试直接返回任务:
This is why you're seeing an exception if you try to return the task directly:
public static Task<byte[]> FromYouTubeAsync(string videoUri)
{
using (var client = new HttpClient())
{
return FromYouTubeAsync(...);
}
}
这code开始下载,则配置了的HttpClient
的,然后返回任务。 的HttpClient
它处置时,将取消所有未完成的操作。
This code is starting the download, then disposing the HttpClient
, and then returning the task. HttpClient
will cancel any outstanding operations when it is disposed.
使用code 等待
将(异步)等待HTTP操作来完成其配置在<code>的HttpClient 。这是你需要的行为,而等待
是前preSS是最彻底的方法。在这种情况下,它不是一个资源浪费可言,因为你的有无的推迟,直到处理完成下载后。
The code using await
will (asynchronously) wait for the HTTP operation to complete before it disposes the HttpClient
. That is the behavior you need, and await
is the cleanest way to express it. In this case, it's not a "waste of resources" at all, because you have to defer disposing until after the download completes.
这篇关于TaskCanceledException时不等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!