【问题标题】:WebApi unable to return to HttpClientWebApi 无法返回 HttpClient
【发布时间】:2016-11-27 17:14:53
【问题描述】:

当我尝试从HttpClient(MVC 应用程序)调用GetAllFiles() 时,它在大括号结束后卡住了。我可以在调试模式下看到数据,但是当到达结束大括号时它会卡住。

当我从 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;
    }
}

【问题讨论】:

    标签: c# asp.net-mvc asp.net-web-api asp.net-web-api2 google-api-dotnet-client


    【解决方案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 返回未完成的Task,表示GetJsonAsync 方法未完成。 顶级方法同步阻塞 GetJsonAsync 返回的任务。这会阻塞上下文线程。 ... 最终,REST 请求将完成。这样就完成了 GetStringAsync 返回的任务。 GetJsonAsync 的延续现在已准备好运行,它等待上下文可用,以便可以在上下文中执行。 僵局。顶级方法是阻塞上下文线程,等待 GetJsonAsync 完成,而 GetJsonAsync 正在等待上下文空闲以便它可以完成。

    解决您的问题(同样,摘自博文):

    在您的“库”异步方法中,尽可能使用 ConfigureAwait(false)。 不要阻塞任务;一直使用异步。

    【讨论】:

    • 谢谢伊兰。这真的帮助了我很多。博客链接对我帮助很大。
    • 第一次遇到这个问题时,我很头疼,很高兴能帮上忙!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多