gpt4 book ai didi

c# - 不等待时出现 TaskCanceledException

转载 作者:行者123 更新时间:2023-11-30 19:57:11 25 4
gpt4 key购买 nike

每当我按照 When at last you await 中的指南同步返回另一个任务而不是等待它时,我似乎得到一个 TaskCanceledException .

TaskCanceledException 代码

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);
}
}

无异常代码

在这里,方法签名的第一次重载被更改为异步,并等待第二次重载。出于某种原因,这会阻止 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);
}
}

为什么会发生这种情况,我能做些什么来解决它(除了等待方法,如上面的链接所述,它会浪费资源)?

最佳答案

对不起,link you posted是关于应用优化的,只有当方法在其await 之后什么都不做时才适用。引用帖子:

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...

在您的示例中,任务代表方法中的最后一条语句。再看一遍:

public async static Task<byte[]> FromYouTubeAsync(string videoUri)
{
using (var client = new HttpClient())
{
return await FromYouTubeAsync(...);
}
}

await 之后 发生了一些事情:特别是 client 的处置。因此,该博文中提到的优化不适用于此处

这就是为什么您在尝试直接返回任务时会看到异常:

public static Task<byte[]> FromYouTubeAsync(string videoUri)
{
using (var client = new HttpClient())
{
return FromYouTubeAsync(...);
}
}

此代码开始下载,然后处理 HttpClient,然后返回任务。 HttpClient 将在处理时取消任何未完成的操作。

使用 await 的代码将(异步地)等待 HTTP 操作完成,然后再处理 HttpClient。这就是您需要的行为,await 是最简洁的表达方式。在这种情况下,它根本不是“资源浪费”,因为您必须将处理推迟到下载完成之后。

关于c# - 不等待时出现 TaskCanceledException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31195467/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com