2011-07-21 12 views
17

Usando la última CTP5 con asíncrono/espera de palabras clave, escribí algo de código, que al parecer no puede compilar:¿Cómo se escribe el método asíncrono simple?

class Program 
    { 
     public class MyClass 
     { 
      async public Task<int> Test() 
      { 
       var result = await TaskEx.Run(() => 
        { 
         Thread.Sleep(3000); 
         return 3; 
        }); 
       return result; 
      } 
     } 

     static void Main(string[] args) 
     { 
      var myClass = new MyClass(); 

      //The 'await' operator can only be used in a method or lambda marked with the 'async' modifier error ??!! 
      int result = await myClass.Test(); 

      Console.ReadLine(); 
     } 
    } 

¿Cuál es º razón de "El operador 'esperar' sólo se puede utilizar en un método o lambda marcado con el error del modificador 'async'? " (He seleccionado la línea a la que me apunta Visual Studio)

Respuesta

8

No sé si puede marcar Main como async, pero debe incluir la palabra clave async en la declaración de cualquier método que use await. Por ejemplo:

public async void DoStuffAsync() 
{ 
    var myClass = new MyClass(); 

    int result = await myClass.TestAsync(); 
} 
+1

Usted puede * * declarar '' Main' como async', y 'await'ing nada en ella * se * poner fin a su programa de – dlev

+0

(suponiendo que tiene ningún otro subproceso de primer plano en ejecución.) Duh, seguí pensando que el error está dentro de mi método de prueba. Visual Studio debería ser más informativo con este error (como "método principal debe asincrónico") – ghord

+8

En la versión C# 5, si marcas Main como async, obtienes un error: "No se puede marcar un punto de entrada con 'async' 'modificador' – Anthony

4

await no es lo mismo que Wait(); haciendo un await es una reescritura significativa de ese método, y en particular afecta la expectativa de cómo ese método sale de la persona que llama. Tiene razón en que en realidad no hace mucho (advertencia: tipos de retorno) excepto decirle al compilador que habilite algunas cosas (como lo hacen los switches como unsafe, checked y unchecked si lo piensa) - pero considere: esto en realidad importa enormemente en su ejemplo. Si sale Main() (y suponemos que no hay otros subprocesos) - usted exe es brindis. Ido. Ya no existe. Agregar async lo hace considerar que solo porque el método sale de no significa que tiene terminado. Realmente no desea que Main() salga antes de estar listo.

Como efecto secundario, este conmutador también formaliza que el método solo puede devolver cosas como Task; sin el interruptor, es posible que tengas la tentación de hacerlo asincrónico más tarde, lo que podría ser un cambio significativo.

+2

Es un programa * ex *. – dlev

+0

@dlev nice Monty Python allí; p –

3

Un método asíncrono puede tener un tipo de vacío o Tarea de retorno. Si el tipo de devolución no es nulo, la persona que llama puede seguir usando el mecanismo de Espera estándar introducido en .Net 4 dentro del método de entrada Principal (que no se puede marcar como sincronización). He aquí un ejemplo sencillo:

static void Main(string[] args) 
    { 
     string address = "http://api.worldbank.org/countries?format=json"; 
     Task t = LoadJsonAsync(address); 
     // do other work while loading 
     t.Wait(); 

     Console.WriteLine("Hit ENTER to exit..."); 
     Console.ReadLine(); 
    } 

    private async static Task LoadJsonAsync(string address) 
    { 
     HttpClient client = new HttpClient(); 

     HttpResponseMessage response = await client.GetAsync(address); 

     // Check that response was successful or throw exception 
     response.EnsureSuccessStatusCode(); 

     // Read response asynchronously as JsonValue and write out top facts for each country 
     JsonArray readTask = await response.Content.ReadAsAsync<JsonArray>(); 
     Console.WriteLine("First 50 countries listed by The World Bank..."); 
     foreach (var country in readTask[1]) 
     { 
      Console.WriteLine(" {0}, Capital: {1}", 
       country.Value["name"], 
       country.Value["capitalCity"]); 
     } 

    } 
+23

Odio cómo todo el mundo siempre usa client.GetAsync como el ejemplo. El póster probablemente sabe cómo usar el método asincrónico de otra persona. ¿Cómo escribes * uno? (por ejemplo, usando el ejemplo Sleep) – Jeff

+0

¿Qué pasa si su tarea asíncrona arroja un resultado? Llamar a task.wait devuelve un booleano. ¿Cómo haría para esperar y luego usar el resultado devuelto? EDITAR: No importa. 'Task.Result'. – Kyle

+0

no estoy seguro, pero ¿no necesita comenzar la Tarea t antes de Esperar() - ing por ello? 't.Start(); t.Wait(); ' – Prokurors

Cuestiones relacionadas