2012-03-21 5 views
5

Questo è solo un semplice compito asincrono ma ho sempre avuto strani errori del compilatore. Questo codice da un servizio API Web in un progetto ASP.NET 4, creato con VS2010.Cosa c'è di sbagliato con questo metodo Task asincrono?

Anche ContinueWith (non generico) restituisce l'attività in modo implicito ma questo errore esiste ancora.

Codice:

public class TestController : ApiController 
{ 
     public Task<HttpResponseMessage> Test() 
     { 
      string url = "http://www.stackoverflow.com"; 
      var client = new HttpClient(); 

      return client.GetAsync(url).ContinueWith<HttpResponseMessage>((request) => 
      { 
       // Error 361 'System.Threading.Tasks.Task' does not contain a definition 
       // for 'Result' and no extension method 'Result' accepting a first argument 
       // of type 'System.Threading.Tasks.Task' could be found 
       // (are you missing a using directive or an assembly reference?) 
       var response = request.Result; 
       response.EnsureSuccessStatusCode(); 

       // Error 364 Cannot implicitly convert type 'System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage>' to 'System.Net.Http.HttpResponseMessage' 
       return response.Content.ReadAsStringAsync().ContinueWith<HttpResponseMessage>((read) => 
       { 
        return new HttpResponseMessage(); 
       }); 
      }); 
     } 
} 

risposta

5

L'errore 364 è perfettamente normale, perché si restituisce un Task<Task<HttpResponseMessage>> invece di Task<HttpResponseMessage>. Una volta risolto il problema, l'errore 361 scompare.

Così si potrebbe Unwrap il risultato:

public Task<HttpResponseMessage> Test() 
{ 
    string url = "http://www.stackoverflow.com"; 
    var client = new HttpClient(); 
    return client.GetAsync(url).ContinueWith(request => 
    { 
     var response = request.Result; 
     response.EnsureSuccessStatusCode(); 
     return response.Content.ReadAsStringAsync().ContinueWith(t => 
     { 
      var result = new HttpResponseMessage(); 
      response.CreateContent(t.Result); 
      return response; 
     }); 
    }).Unwrap(); 
} 
+0

Grazie, ho terribilmente dimenticato che il valore di ritorno è stato avvolto in una Task <> per ogni ContinueWidth. Il tuo codice è compilato ora, ma non sono sicuro che funzioni ancora come mi aspettavo: il thread sarà libero per un po 'durante il client di esecuzione. GetAsync e response.Content.ReadAsStringAsync chiama? –

+0

@Tiendq, ho aggiornato la mia risposta con un esempio migliore usando 'Unwrap'. Ciò assicurerà che il thread di lavoro sarà libero durante l'esecuzione della richiesta HTTP. –