Как задача становится 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 78

2 ответа:

происходит ли неявное преобразование между Task и int?

Неа. Это только часть того, как async/await строительство.

любой метод объявлен как async должно иметь тип возврата:

  • void (избегайте, если это возможно)
  • Task (нет результата, кроме уведомления о завершении / сбое)
  • Task<T> (для логического результата типа T в асинхронном манера)

компилятор выполняет все соответствующие обертывания. Дело в том, что ты асинхронно возвращение urlContents.Length - вы не можете сделать метод просто вернуть int, как фактический метод вернется, когда он попадает в первый await выражение, которое еще не завершено. Поэтому вместо этого он возвращает Task<int> который завершится, когда завершится сам асинхронный метод.

отметим, что await совсем наоборот - это разворачивает a Task<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; конечно.)

нет требует преобразования задачи в int. Просто Используйте Результат Задачи.

int taskResult= AccessTheWebAndDouble.Result;    

public async Task<int> AccessTheWebAndDouble()
{
int task = AccessTheWeb();
return task;

}

он вернет значение, если доступно в противном случае он возвращает 0.