Task.ContinueWith 应该如何调用另一个异步方法

问题描述 投票:0回答:0

我有两个异步方法,一个调用获取实体的 API,另一个返回依赖于第一个实体的另一个实体。例如,REST API 中的产品和产品类别,例如

GET /api/products/{productID}
返回与 ID 匹配的产品,而
GET /api/products/{productId}/category
返回与产品 ID 匹配的产品类别。

在这种情况下,我们使用方法HttpClient.GetFromJsonAsync(HttpClient, String, CancellationToken) 两次,每次调用一次。使用 ContinueWith 方法,我们基本上得到一个任务的任务(类型是

Task<Task<ProductCategory>>
)。

哪种方法更好?

using System.Net.Http.Json;

using var httpClient = new HttpClient();

ProductCategory? category;


//  Use "await await"
category = await await httpClient
    .GetFromJsonAsync<Product>("https://apiexample.com/api/products/1234")
        .ContinueWith(task => httpClient
            .GetFromJsonAsync<ProductCategory>($"https://apiexample.com/api/categories/{task.Result?.CategoryId}"));

//  Use await and Task<TResult>.Result
category = await httpClient
    .GetFromJsonAsync<Product>("https://apiexample.com/api/products/1234")
        .ContinueWith(task => httpClient
            .GetFromJsonAsync<ProductCategory>($"https://apiexample.com/api/categories/{task.Result?.CategoryId}").Result);

//  Use unwrap and await
category = await httpClient
    .GetFromJsonAsync<Product>("https://apiexample.com/api/products/1234")
        .ContinueWith(task => httpClient
            .GetFromJsonAsync<ProductCategory>($"https://apiexample.com/api/categories/{task.Result?.CategoryId}"))
        .Unwrap();

//  Do not use ContinueWith at all
var product = await httpClient.GetFromJsonAsync<Product>("https://apiexample.com/api/products/1234");
category = await httpClient.GetFromJsonAsync<ProductCategory>($"https://apiexample.com/api/categories/{product?.CategoryId}");

Console.WriteLine(category);
Console.WriteLine("Done.");


class Product
{
    public int ProductId { get; set; }
    public int? CategoryId { get; set; }
    public string? ProductName { get; set; }
}

class ProductCategory
{
    public int CategoryId { get; set; }
    public string? CategoryName { get; set; }
    public override string ToString() => $"[CategoryID: {CategoryId}; CategoryName: {CategoryName}]";
}
c# .net dotnet-httpclient
© www.soinside.com 2019 - 2024. All rights reserved.