C#-将异步任务从一种类型转换为另一种类型
本文关键字:一种 类型转换 类型 另一种 异步 任务 C#- | 更新日期: 2023-09-27 17:59:10
我习惯于使用Scala编程语言——使用Scala我可以映射未来,例如:
val response: Future[HttpResponse] = asyncHttpClient.GetRequest("www.google.com")
val statusCode: Future[Int] = response.map(r => r.statusCode)
最近,我开始使用C#,我发现自己的处境与上面的例子相同,但我不知道如何"映射"任务。
下面是我想要实现的一个例子:
Task<HttpResponseMessage> response = httpClient.GetAsync("www.google.com")
Task<int> statusCode = response.Map(response => response.StatusCode)
感谢
现有方法最直接的翻译是:
Task<int> statusCode = response.ContinueWith(t => t.Result.StatusCode)
然而,在实践中,你几乎总是在等待任务的结果。也许您应该研究async/await。
老实说,我有点惊讶框架中没有任何内容。(更有可能的是,还有一个我没有见过的。)不过你可以很容易地构建它:
public static async Task<TResult> Map<TSource, TResult>
(Task<TSource> task, Func<TSource, TResult> selector)
=> selector(await task.ConfigureAwait(false));
注意:这里使用ConfigureAwait
并不总是明确的。您可能需要包含continueOnCapturedContext
参数:
public static async Task<TResult> Map<TSource, TResult>(
Task<TSource> task,
Func<TSource, TResult> selector,
bool continueOnCapturedContext = false) =>
selector(await task.ConfigureAwait(continueOnCapturedContext));
使用现代C#,应该使用await
:重写
var response = await httpClient.GetAsync("www.google.com")
var statusCode = response.StatusCode;
这可以与async
一起使用,以创建Task<int>
:
async Task<int> Fetch(string url)
{
var response = await httpClient.GetAsync(url);
return response.StatusCode;
}