繁体   English   中英

转换方法以使用异步

[英]Convert a method to use async

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

无论如何,代码都连接到LDAP存储并验证用户的帐户等。我已经尝试了各种尝试,但是这里只是缺少了一些东西。 我将代码恢复到以前的样子。.感谢任何指导以使其正确支持异步...

这是代码:

public async Task<User> GetAsyncADUser(PrincipalContextParameter param)
    {
        try
        {

            if (UseLDAPForIdentityServer3)
            {
                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;
                        }
                    }
                }
            }

        }
        catch (Exception ex)
        {
            throw;
        }

        return null;

    }

MSDN

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

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

    • Task<TResult>如果您的方法具有一个返回语句,其中操作数的类型为TResult
    • Task ,如果你的方法没有返回语句或具有不带操作数return语句。
    • 如果您正在编写异步事件处理程序,则该方法Void
  • 该方法通常至少包含一个await表达式 ,该表达式标记了直到等待的异步操作完成后该方法才能继续的点。 同时,该方法被挂起,控制权返回给该方法的调用者。 本主题的下一部分说明了在挂起点发生的情况。

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

User user = await GetAsyncADUser();

这样,你不需要使用async关键字的方法GetAsyncADUser ,但你需要标记使用的代码与上面的一致方法async关键字。

可以保留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;
}

就像它说的那样,您的代码是同步的。 如果您在Task中包装了UserPrincipal.FindByIdentityPrincipalContext.ValidateCredentials并将其返回,则可以使其异步工作。

正如Stephen Cleary的评论所说,如果有一个较低的级别,您可以异步执行工作,在那里执行并将异步/等待传递到该级别。 虽然不知道这些方法的模样很难说。

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;

    }

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

例如,如果方法UserPrincipal.FindByIdentity()是一个异步方法(返回Task<UserPrincipal> ),则可以像这样等待它:

UserPrincipal userPrincipal = await UserPrincipal.FindByIdentity();

但是,它不是异步方法,因此没有任何等待。 您可以在这里做的一件事是将要异步运行的代码包装在一个辅助方法中,通过Task.Run(() => RunMeAsync());执行该辅助方法Task.Run(() => RunMeAsync()); 并等待刚刚开始的新任务的结果。

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

其中, RunMeAsync()是要异步运行的帮助程序方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM