我们有这种方法:
async Task<int> AccessTheWebAsync() { HttpClient client = new HttpClient(); Task<string> getStringTask = client.GetStringAsync("msdn.microsoft"); // You can do work here that doesn't rely on the string from GetStringAsync. DoIndependentWork(); string urlContents = await getStringTask; //The thing is that this returns an int to a method that has a return type of Task<int> return urlContents.Length; }在 Task< int>之间是否发生隐式转换? 和 int ?如果没有,那是怎么回事?
Does an implicit conversion occur between Task<int> and int? If not, then what is happening? How is it implemented to work?
推荐答案
在Task<>和int之间是否进行隐式转换? ?
Does an implicit conversion occur between Task<> and int?
不是。这只是 async / await 工作方式的一部分。
Nope. This is just part of how async/await works.
任何声明为 async 的方法都必须具有以下返回类型:
Any method declared as async has to have a return type of:
- void (尽可能避免)
- 任务(除了通知以下内容之外没有其他结果)完成/失败)
- Task< T> (对于 T 以异步方式)
- void (avoid if possible)
- Task (no result beyond notification of completion/failure)
- Task<T> (for a logical result of type T in an async manner)
编译器会进行所有适当的包装。关键是您异步返回 urlContents.Length -您不能使该方法仅返回 int ,因为当实际方法到达尚未完成的第一个 await 表达式时,它将返回。因此,相反,它返回 Task< int> ,该方法将在异步方法本身完成时完成。
The compiler does all the appropriate wrapping. The point is that you're asynchronously returning urlContents.Length - you can't make the method just return int, as the actual method will return when it hits the first await expression which hasn't already completed. So instead, it returns a Task<int> which will complete when the async method itself completes.
await 的作用相反-将 Task< T> 展开 $ c> T 值,这是这行的工作方式:
Note that await does the opposite - it unwraps a Task<T> to a T value, which is how this line works:
string urlContents = await getStringTask;...但是当然,它会以异步方式解包,而只使用 Result 将阻塞,直到任务完成。 ( await 可以解开实现等待模式的其他类型,但是 Task< T> 是您可能会选择的类型。
... but of course it unwraps it asynchronously, whereas just using Result would block until the task had completed. (await can unwrap other types which implement the awaitable pattern, but Task<T> is the one you're likely to use most often.)
这种双重包装/展开功能可以使async如此组合。例如,我可以编写另一个异步方法,该方法调用您的异步方法并将结果加倍:
This dual wrapping/unwrapping is what allows async to be so composable. For example, I could write another async method which calls yours and doubles the result:
public async Task<int> AccessTheWebAndDoubleAsync() { var task = AccessTheWebAsync(); int result = await task; return result * 2; }(或者简单地返回以等待访问AccessTheWebAsync()* 2 ; 当然。)
更多推荐
Task< int>如何成为一个int?
发布评论