繁体   English   中英

HttpClient PostAsync() 从不返回响应

[英]HttpClient PostAsync() never return response

我的问题与这里的这个问题非常相似。 我有一个AuthenticationService类,它创建一个HttpClient PostAsync()并且当我从 ASP 项目运行它时从不返回结果,但是当我在控制台应用程序中实现它时它工作得很好。

这是我的身份验证服务类:

public class AuthenticationService : BaseService
{
    public async Task<Token> Authenticate (User user, string url)
    {
        string json = JsonConvert.SerializeObject(user);
        StringContent content = new StringContent(json, Encoding.UTF8, "application/json");

        HttpResponseMessage response = await _client.PostAsync(url, content);
        string responseContent = await response.Content.ReadAsStringAsync();
        Token token = JsonConvert.DeserializeObject<Token>(responseContent);

        return token;
    }
}

它就在这里挂起: HttpResponseMessage response = await _client.PostAsync(url, content);

这是我的控制器调用服务:

public ActionResult Signin(User user)
{
    // no token needed to be send - we are requesting one
    Token token =  _authenticationService.Authenticate(user, ApiUrls.Signin).Result;
    return View();
}

这是我如何使用控制台应用程序测试服务的示例,它运行得很好。

class Program
{
    static void Main()
    {
        AuthenticationService auth = new AuthenticationService();

        User u = new User()
        {
            email = "email@hotmail.com",
            password = "password123"
        };

        Token newToken = auth.Authenticate(u, ApiUrls.Signin).Result;

        Console.Write("Content: " + newToken.user._id);
        Console.Read();
    }
}

由于您使用的是.Result ,这最终会导致您的代码出现死锁。 这在控制台应用程序中工作的原因是因为控制台应用程序没有上下文,但 ASP.NET 应用程序有(请参阅Stephen Cleary 的不要阻止异步代码)。 你应该把Signin在您的控制器方法asyncawait调用_authenticationService.Authenticate来解决死锁问题。

由于您正在使用.Result.Waitawait这最终会导致您的代码死锁

您可以在async方法中使用ConfigureAwait(false)防止死锁

像这样:

string responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

您可以尽可能将ConfigureAwait(false)用于 Don't Block Async Code 。

如果有人来需要查看代码,我只需将控制器更改为如下所示:

    /***
    *** Added async and Task<ActionResult>
    ****/
    public async Task<ActionResult> Signin(User user)
    {
        //no token needed - we are requesting one
        // added await and remove .Result()
        Token token =  await _authenticationService.Authenticate(user, ApiUrls.Signin);

        return RedirectToAction("Index", "Dashboard", token.user);
    }

谢谢大家的快速回复!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM