转换方法以使用异步

时间:2016-08-12 19:40:17

标签: c# asynchronous ldap owin identityserver3

我正在转换身份验证过程以支持异步,VS 2015 IDE警告我以下消息: async方法缺少'await'运算符并将同步运行...... 等...

无论如何,代码连接到LDAP商店并验证用户的帐户等... 我已经尝试了各种各样的事情,但我在这里错过了一些东西。我把代码恢复到以前的状态..我很感激任何指导,让它正确支持异步...

以下是代码:

$onChanges

4 个答案:

答案 0 :(得分:2)

来自MSDN

以下特征总结了异步方法的原因:

  • 方法签名包含异步修饰符。
  • 按照惯例,async方法的名称以“Async”后缀结尾。 返回类型是以下类型之一:

    • Task<TResult>如果您的方法有一个返回语句,其中操作数的类型为TResult
    • Task如果您的方法没有return语句或者没有操作数的return语句。
    • Void如果您正在编写异步事件处理程序。
  • 该方法通常至少包含一个等待表达式,它标记了在等待异步操作完成之前方法无法继续的点。在此期间,该方法被暂停,并且控制返回到方法的调用者。本主题的下一部分说明了暂停点会发生什么。

您可以使用return Task.Run(() => { /* your code here */ })并返回Task<User>。然后您可以将此方法称为:

User user = await GetAsyncADUser();

这样,您无需在方法async中使用GetAsyncADUser关键字,但您需要使用async标记使用上述代码行的方法关键字。

答案 1 :(得分:1)

可以保留try catch块....要运行代码异步,只需将其置于Task.Run中的操作中:

public async Task<User> GetAsyncADUser(PrincipalContextParameter param)
{        
    if (UseLDAPForIdentityServer3)
    {
        return await Task.Run() =>
        {
            using (var pc = new PrincipalContext(ContextType.Domain, param.ADDomain, param.ADServerContainer, param.ADServerUser, param.ADServerUserPwd))
            {
                UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(pc, param.UserNameToValidate);
                if (userPrincipal != null)
                {
                    bool isvalid = pc.ValidateCredentials(userPrincipal.DistinguishedName, param.UserPasswordToValidate, ContextOptions.SimpleBind);

                    if (isvalid)
                    {
                        User user = new User { ad_guid = userPrincipal.Guid.ToString(), Username = param.UserNameToValidate, Password = param.UserPasswordToValidate };
                        return user;
                    }
                }
            }
        }
    }
    return null;
}

答案 2 :(得分:0)

就像它说的那样,你的代码是同步的。如果你在任务中包装UserPrincipal.FindByIdentityPrincipalContext.ValidateCredentials并执行任何操作并返回它,那么你可以让它的工作异步。

正如Stephen Cleary的评论所说,如果有一个较低的级别你可以在异步中执行工作,那么在那里执行并将async / await传递到此级别。很难说不知道那些方法是什么样的。

public Task<UserPrincipal> FindByIdentity (PrincipalContext pc, string username)
    {
        return Task.Run(() =>
        {
            // Do the thing;
        });
    }

这将允许你等待它们,你的代码将是异步的。

public async Task<User> GetADUserAsync(PrincipalContextParameter param)
    {
        try
        {
            if (UseLDAPForIdentityServer3)
            {
                using (var pc = new PrincipalContext(ContextType.Domain, param.ADDomain, param.ADServerContainer, param.ADServerUser, param.ADServerUserPwd))
                {
                    UserPrincipal userPrincipal = await UserPrincipal.FindByIdentity(pc, param.UserNameToValidate);
                    if (userPrincipal != null)
                    {
                        bool isvalid = await pc.ValidateCredentials(userPrincipal.DistinguishedName, param.UserPasswordToValidate, ContextOptions.SimpleBind);

                        if (isvalid)
                        {
                            User user = new User { ad_guid = userPrincipal.Guid.ToString(), Username = param.UserNameToValidate, Password = param.UserPasswordToValidate };
                            return user;
                        }
                    }
                }
            }

        }
        catch (Exception ex)
        {
            throw;
        }

        return null;

    }

答案 3 :(得分:0)

它出现在这个代码块中没有等待的异步调用....我的意思是,没有方法调用返回任务。

例如,如果方法UserPrincipal.FindByIdentity()是异步方法,(返回Task<UserPrincipal>)那么可以等待它:

UserPrincipal userPrincipal = await UserPrincipal.FindByIdentity();

但是,它不是一种异步方法,因此没有什么值得期待的。你可以做的一件事是在helper方法中包装你想要异步运行的代码,通过Task.Run(() => RunMeAsync());执行那个helper方法,然后等待你刚刚开始的新任务的结果。

var result = await Task.Run(() => RunMeAsync());

其中RunMeAsync()是您要异步运行的辅助方法。