如何使异步调用在c#

时间:2016-12-22 10:24:30

标签: c# asp.net-identity membership-provider

我有这个代码

ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password)

我希望这段代码能够同步运行,因为我的下一个陈述依赖于此。以下调用大多数时间都会失败,因为用户为空。

var roles = await userManager.GetRolesAsync(user.Id);

有什么建议吗?

3 个答案:

答案 0 :(得分:3)

代码没有问题。 await表示在后面的异步方法完成后,仅继续执行。这意味着在此代码段中:

var user = await userManager.FindAsync(context.UserName, context.Password)
var roles = await userManager.GetRolesAsync(user.Id);

上一行完成后,只会执行对GetRolesAsync的调用。

来自UserManager.FindAsync

的文档
  

返回具有指定用户名和密码的用户,如果没有匹配则返回null。

用户名或密码错误。只需向最终用户返回一条消息,要求他们重试。如果您使用存储的凭据进行此呼叫,请再次检查它们。

在任何情况下,您都需要在尝试使用user值之前检查身份验证失败,例如:

var user = await userManager.FindAsync(context.UserName, context.Password)
if (user == null)
{
    //Somehow report failure, decrement retry counters, etc
    retries--;
    return false;
}
else 
{
    var roles = await userManager.GetRolesAsync(user.Id);
    ....
}

答案 1 :(得分:0)

ApplicationUser user = userManager.FindAsync(context.UserName, context.Password).Result;
var roles = userManager.GetRolesAsync(user.Id).Result;

但是如果上下文用户只是为null,那么如果你同步执行它将无法帮助你 - 用户将像以前一样为NULL。

如果您尝试向应用程序添加登录信息,可能有助于查看this 此外,您应该使用policies而不是角色。

修改
好的,没有死锁问题,我没有意识到(感谢@hvd):

var user = Task.Run(() => userManager.FindAsync(context.UserName, context.Password)).Result;
var roles = Task.Run(() => userManager.GetRolesAsync(user.Id)).Result;

如果异步方法返回void

Task.Run( () => asyncMethod()).Wait();

答案 2 :(得分:0)

我不明白为什么会出现问题 - 如果await正确,user应在GetRolesAsync电话之前正确提取。这是你的整个代码吗?

Mayby,usernull,因为它不存在?

此外,您可以链接您的呼叫而不是同步运行它:

var roles = await userManager.FindAsync(context.UserName, context.Password)
                             .ContinueWith(task => 
                                              userManager.GetRolesAsync(task.Result.Id))
                             .Unwrap();