我有两个异步方法,一个调用获取实体的 API,另一个返回依赖于第一个实体的另一个实体。例如,REST API 中的产品和产品类别,例如
GET /api/products/{productID}
返回与 ID 匹配的产品,而 GET /api/products/{productId}/category
返回与产品 ID 匹配的产品类别。
在这种情况下,我们使用方法HttpClient.GetFromJsonAsync
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}]";
}