【发布时间】:2017-08-25 01:55:53
【问题描述】:
如果我们有一个具有async 修饰符但不使用await 运算符的方法,C# 编译器已经警告我们。
根据this 的回答,将await 添加到异步方法的末尾是没有意义的(在这种情况下,只需删除async 修饰符)。
但是,如果该方法在调用后续真正的异步方法之前需要执行昂贵的同步操作怎么办?
例如,如果我使用的是HttpClient:
private readonly HttpClient client = ...
public Task<HttpResponseMessage> CallMyWebServiceMethod() {
HttpRequestMessage request = this.SomeExpensiveButSynchronousMethod();
return this.client.SendAsync( request );
}
这段代码会阻塞调用者(由于SomeExpensiveButSynchronousMethod)。
但是,如果我将代码更改为:
public async Task<HttpResponseMessage> CallMyWebServiceMethod() {
HttpRequestMessage request = this.SomeExpensiveButSynchronousMethod();
return await this.client.SendAsync( request );
}
我这样称呼它:
HttpResponse response = await myWrapper.CallMyWebServiceMethod();
...我知道 TPL 会立即启动一个后台线程,然后在后台线程中运行 CallMyWebServiceMethod,恢复父代码想要的任何内容,使整个调用在进程中非阻塞,然后在任务完成并返回HttpResponse。
...如果是这样的话,那似乎是矛盾的。
如果我错了,并且调用 一直阻塞,直到它到达 SendAsync,那么我如何在 HttpClient 用于其请求的同一后台线程上执行 SomeExpensiveButSynchronousMethod ?
【问题讨论】:
-
这确实是更具体的实现。您希望请求是异步的还是同步的(阻塞)?
-
@Tdorno 我想用我自己的操作包装
HttpClient,以一种“保留”异步性的方式——假设这是我们应该做的。
标签: c# async-await