0

Es bleibt nach dem Ende geschweiften Klammern stecken, wenn ich versuche, GetAllFiles() von HttpClient (MVC-Anwendung) aufzurufen. Ich kann die Daten im Debug-Modus sehen, aber beim Erreichen der End-Klammer bleibt sie hängen.WebApi kann nicht zu HttpClient zurückkehren

Wenn ich die gleiche WebApi-Methode vom Postboten anrufe, kann ich leicht die Daten bekommen.

public class FileToDriveController : ApiController 
{ 
    public IHttpActionResult GetAllFiles() 
    { 
     //Gets credentials 
     GoogleUtility googleUtility = new GoogleUtility(); 
     UserCredential credential = googleUtility.GetCredential(); 

     var service = new DriveService(new BaseClientService.Initializer() 
     { 
      HttpClientInitializer = credential, 
      ApplicationName = "DriveApiFileUpload" 
     }); 

     var listRequest = service.Files.List(); 
     listRequest.MaxResults = 10; 

     IList<Google.Apis.Drive.v2.Data.File> files = listRequest.Execute().Items; 

     if(files!=null) 
     { 
      return Ok(files); //i can see files here in debug mode 
     } 

     return InternalServerError(); 
    } 
} 

Dies ist die Forderung des Httpclient an den api

public async Task<HttpResponseMessage> getAllFiles() 
{ 
    using (var client = new HttpClient()) 
    { 
     client.BaseAddress = new Uri("http://localhost:16184/"); 
     client.DefaultRequestHeaders.Accept.Clear(); 
     client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

     HttpResponseMessage message = await client.GetAsync("api/FileToDrive/GetAllFiles"); 

     if (message.StatusCode == HttpStatusCode.OK) 
     { 
      return message; 
     } 
     return null; 
    } 
} 

Antwort

1

Ihr Problem ist ein knifflige Frage, die von einem Deadlock verursacht, wenn async Anrufe aus einem Controller zu machen. Sehen Sie sich diese ausgezeichnete Erklärung an: http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

Die Top-Level-Methode ruft GetJsonAsync (im UI/ASP.NET-Kontext) auf. GetJsonAsync startet die REST-Anforderung durch Aufrufen von HttpClient.GetStringAsync (immer noch im Kontext). GetStringAsync gibt eine nicht abgeschlossene Aufgabe zurück, die angibt, dass die REST-Anforderung nicht vollständig ist. GetJsonAsync wartet auf die von GetStringAsync zurückgegebene Aufgabe. Der Kontext wird erfasst und verwendet, um die GetJsonAsync-Methode später fortzusetzen. GetJsonAsync gibt eine unvollständige Aufgabe zurück, die angibt, dass die GetJsonAsync-Methode nicht abgeschlossen ist. Die Methode auf oberster Ebene blockiert synchron den von GetJsonAsync zurückgegebenen Task. Dies blockiert den Kontext-Thread. ... Schließlich wird die REST-Anforderung abgeschlossen. Dies schließt die Task ab, die von GetStringAsync zurückgegeben wurde. Die Fortsetzung für GetJsonAsync kann jetzt ausgeführt werden und wartet darauf, dass der Kontext verfügbar ist, damit er im Kontext ausgeführt werden kann. Deadlock. Die Methode auf oberster Ebene blockiert den Kontext-Thread und wartet darauf, dass GetJsonAsync abgeschlossen wird, und GetJsonAsync wartet darauf, dass der Kontext frei ist, damit er abgeschlossen werden kann.

In Ihren „Bibliothek“ Asynchron-Methoden verwenden ConfigureAwait (false), wo immer möglich:

Um Ihr Problem (wieder genommen aus der Blog-Post) zu lösen. Blockieren Sie nicht bei Aufgaben; verwende async den ganzen Weg hinunter.

+0

Danke Eran. Das hat mir sehr geholfen. Der Link zum Blog hat mir sehr geholfen. –

+0

Ich bekam Kopfschmerzen, als ich das erste Mal darauf stieß. Ich bin froh, dass ich helfen konnte! – PartlyCloudy

Verwandte Themen