私の問題はこれに非常に似ています 質問 ここに。 AuthenticationService
PostAsync()
を作成するHttpClient
クラスがあり、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 protected]",
password = "password123"
};
Token newToken = auth.Authenticate(u, ApiUrls.Signin).Result;
Console.Write("Content: " + newToken.user._id);
Console.Read();
}
}
_
.Resultを使用しているため、これによりコードでデッドロックが発生します。これがコンソールアプリケーションで機能するのは、コンソールアプリケーションにコンテキストがないためですが、ASP.NETアプリにはあります( http://blog.stephencleary.com/2012/07/dont-block-onを参照)。 -async-code.html )。コントローラーのSigninメソッドを非同期にし、_authenticationService.Authenticateの呼び出しを待って、デッドロックの問題を解決する必要があります。
誰かが来てコードを見る必要がある場合は、コントローラを次のように変更します:
/***
*** 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);
}
迅速な対応ありがとうございました!
_.Result
_または_.Wait
_またはawait
を使用しているため、コードにdeadlockが発生します。
async
メソッドでConfigureAwait(false)
を使用してデッドロックを防止
このような:
_string responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
_
[非同期コードをブロックしない]では、可能な限り
ConfigureAwait(false)
を使用できます。