转换方法以使用异步

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

无论如何,代码连接到LDAP商店并validation用户的帐户等…我已经尝试了各种各样的东西等待,但我只是在这里遗漏了一些东西。 我把代码恢复到以前的状态..我将非常感谢能够正确支持异步的任何指导…

这是代码:

public async Task 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”后缀结尾。 返回类型是以下类型之一:

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

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

 User user = await GetAsyncADUser(); 

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

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

 public async Task 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; } 

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

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

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

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

 public async Task 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 = await UserPrincipal.FindByIdentity();

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

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

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