Tenemos este método:
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;
}
¿Se produce una conversión implícita entre Task<int>y int? Si no es así, ¿qué está pasando? ¿Cómo se implementa para que funcione?

asyncpalabra clave.Respuestas:
¡No! Esto es solo una parte de cómo funciona
async/await.Cualquier método declarado como
asyncdebe tener un tipo de retorno de:void(evitar si es posible)Task(ningún resultado más allá de la notificación de finalización / falla)Task<T>(para un resultado lógico de tipoTde forma asincrónica)El compilador hace todo el ajuste apropiado. El punto es que está regresando de forma asincrónica
urlContents.Length; no puede hacer que el método simplemente regreseint, ya que el método real regresará cuando llegue a la primeraawaitexpresión que aún no se ha completado. Entonces, en cambio, devuelve unTask<int>que se completará cuando se complete el método asincrónico.Tenga en cuenta que
awaithace lo contrario: desenvuelve unTask<T>a unTvalor, que es como funciona esta línea:... pero, por supuesto, lo desenvuelve de forma asincrónica, mientras que con solo usarlo
Resultse bloquearía hasta que se complete la tarea. (awaitpuede desenvolver otros tipos que implementan el patrón de espera, peroTask<T>es el que probablemente usará con más frecuencia).Este doble envoltorio / desenvolvimiento es lo que permite que async sea tan componible. Por ejemplo, podría escribir otro método asíncrono que llame al suyo y duplique el resultado:
(O simplemente
return await AccessTheWebAsync() * 2;por supuesto).fuente
async/awaity encuentro esto extremadamente poco intuitivo. En mi opinión, debe haber una palabra clave o similar en elreturnpara aclarar esto, por ejemploreturn async result;(de la misma manera queawait result"desenvuelve" elTdeTast<T>).await- conT foo = someTaskT;lo que obtendría "No se puede convertir implícitamente el tipoTask<T>enT" - de la misma manera que yo sostengo que tendría más sentido tener una palabra clave para el inverso (envolviendoTask<T>). Estoy a favor de eliminar la pelusa, pero en este caso creo que proporciona una ofuscación innecesaria dentro de losasyncmétodos. (¡Obviamente el punto es discutible porque los poderes fácticos ya han hablado / codificado!)async, creo que es suficiente.No requiere convertir la tarea a int. Simplemente use el resultado de la tarea.
Devolverá el valor si está disponible; de lo contrario, devolverá 0.
fuente
Result; ¡Puede causar interbloqueos! Considere, por ejemplo, este flujo de trabajo: (1) Escriba una nota que diga "cortar el césped". (2) Espere a que se corte el césped (3) Coma un sándwich, (4) Haga lo que diga en la nota ". Con ese flujo de trabajo, nunca come un sándwich ni corta el césped, porque el paso 2 es una espera sincrónica en algo que harás en el futuro . Pero ese es el flujo de trabajo que estás describiendo aquí.