如何使异步调用在C#中同步运行



我有这个代码

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

我希望该代码件可以同步运行,因为我的下一个语句取决于此。下面的呼叫大部分时间都失败了,因为用户为null。

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

任何建议?

代码没有错。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);
    ....
}
ApplicationUser user = userManager.FindAsync(context.UserName, context.Password).Result;
var roles = userManager.GetRolesAsync(user.Id).Result;

但是,如果上下文用户只是null,那么如果您同步进行操作,则无济于事 - 用户将与以前一样空。

如果您要在应用程序中添加登录名,则可能会有助于检查一下。
另外,您可能应该使用政策而不是角色。

编辑:
好的,没有死锁问题,我不知道(谢谢@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();

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

Mayby,usernull,因为它不存在?

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

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

相关内容

  • 没有找到相关文章

最新更新