Как задача становится int?
у нас есть этот метод.
async Task<int> AccessTheWebAsync()
{
HttpClient client = new HttpClient();
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
// 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? Если нет, то что происходит, как это реализовано для работы?
2 ответа:
происходит ли неявное преобразование между Task и int?
Неа. Это только часть того, как
async
/await
строительство.любой метод объявлен как
async
должно иметь тип возврата:
void
(избегайте, если это возможно)Task
(нет результата, кроме уведомления о завершении / сбое)Task<T>
(для логического результата типаT
в асинхронном манера)компилятор выполняет все соответствующие обертывания. Дело в том, что ты асинхронно возвращение
urlContents.Length
- вы не можете сделать метод просто вернутьint
, как фактический метод вернется, когда он попадает в первыйawait
выражение, которое еще не завершено. Поэтому вместо этого он возвращаетTask<int>
который завершится, когда завершится сам асинхронный метод.отметим, что
await
совсем наоборот - это разворачивает aTask<T>
доT
значение, как работает эта строка:string urlContents = await getStringTask;
... но, конечно, он разворачивает его асинхронно, тогда как просто используя
Result
будет блокировать, пока задача не была завершена. (await
можно развернуть другие типы, которые реализуют ожидаемый шаблон, ноTask<T>
это тот, который вы, вероятно, будете использовать чаще всего.)эта двойная упаковка/разворачивание-это то, что позволяет асинхронности быть настолько композиционной. Например, я мог бы написать еще один асинхронный метод, который вызывает ваш и удваивает результат:
public async Task<int> AccessTheWebAndDouble() { var task = AccessTheWeb(); int result = await task; return result * 2; }
(или просто
return await AccessTheWeb() * 2;
конечно.)