Jam*_* Ko 2 c# asynchronous task async-await
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);
    }
}
为什么会发生这种情况,我该怎么做才能解决它(除了等待上面链接中描述的浪费资源的方法)?
对不起,您发布的链接是关于应用优化的,只有在方法之后不执行任何操作时才适用await.引用帖子:
然而,在这种情况下,我们正在处理一个任务来表示方法中的最后一个语句,因此它实际上已经表示了整个方法的处理......
在您的例子,该任务也不能代表该方法的最后一条语句.再看一遍:
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处置时将取消任何未完成的业务.
使用awaitwill(异步)的代码在处理之前等待HTTP操作完成HttpClient.这是您需要的行为,await是表达它的最简洁方式.在这种情况下,它根本不是"浪费资源",因为在下载完成之前,您必须推迟处置.
| 归档时间: | 
 | 
| 查看次数: | 769 次 | 
| 最近记录: |