HttpClient PostAsync()永远不会返回响应

Eri*_*rik 9 c# asp.net asynchronous httpclient

我的问题与这个问题非常相似.我有一个使用HttpClient PostAsync()的authenticationService类,并且当我从ASP项目运行它时从不返回结果,但是当我在Console App上实现它时,它工作得很好.

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

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

它就在这里挂起

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();
    }
Run Code Online (Sandbox Code Playgroud)

以下是我使用控制台应用程序测试服务的示例,它运行得很好.

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

    }
}
Run Code Online (Sandbox Code Playgroud)

预先感谢您的帮助.

Has*_*thi 18

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

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

像这样:

string responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)

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


小智 17

由于您使用的是.Result,这最终会导致代码死锁.这是在控制台应用程序中工作的原因是因为控制台应用程序没有上下文,但ASP.NET应用程序没有(请参阅http://blog.stephencleary.com/2012/07/dont-block-on-async-code .html).您应该在控制器中使用Signin方法异步并等待对_authenticationService.Authenticate的调用以解决死锁问题.


Eri*_*rik 5

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

    /***
    *** 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);
    }
Run Code Online (Sandbox Code Playgroud)

谢谢大家的快速回复!