0

當我試圖從HttpClient(MVC應用程序)調用GetAllFiles()時,它卡在結束大括號後。我可以在調試模式下看到數據,但是當到達時,結束括號就會卡住。WebApi無法返回到HttpClient

當我從postman調用相同的WebApi方法時,我可以輕鬆地獲取數據。

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(); 
    } 
} 

這是HttpClient的的調用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; 
    } 
} 

回答

1

您的問題是由死鎖使從控制器內的異步調用時造成的一個棘手的一個。看到這個優秀的解釋:http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

頂級方法調用GetJsonAsync(在UI/ASP.NET上下文中)。 GetJsonAsync通過調用HttpClient.GetStringAsync(仍在上下文中)來啓動REST請求。 GetStringAsync返回未完成的任務,指示REST請求未完成。 GetJsonAsync等待GetStringAsync返回的任務。上下文被捕獲並將用於稍後繼續運行GetJsonAsync方法。 GetJsonAsync返回未完成的任務,表明GetJsonAsync方法未完成。 頂級方法同步阻塞GetJsonAsync返回的任務。這會阻止上下文線程。 ...最終,REST請求將完成。這完成了由GetStringAsync返回的任務。 GetJsonAsync的延續現在已準備好運行,並且它等待上下文可用,以便它可以在上下文中執行。 僵局。頂級方法阻塞上下文線程,等待GetJsonAsync完成,並且GetJsonAsync正在等待上下文被釋放以便它可以完成。

爲了解決您的問題(再次,從博客中獲得):

在您的「庫」異步方法,使用ConfigureAwait(假)儘可能。 不要在任務上阻塞;一直使用異步。

+0

謝謝伊蘭。這真的幫了我很多。鏈接到博客幫了我很多。 –

+0

當我第一次遇到這個問題時,我很頭疼,試圖解決這個問題,很高興我能幫上忙! – PartlyCloudy