转换方法以使用异步
Convert a method to use async
我正在转换身份验证过程以支持异步,VS 2015 IDE 警告我以下消息:
异步方法缺少 'await' 运算符,将 运行 同步... 等...
无论如何,代码连接到 LDAP 存储并验证用户的帐户等...
我用 await 尝试了各种方法,但我只是在这里遗漏了一些东西。我将代码恢复到原来的状态。我将不胜感激任何让它正确支持异步的指导......
代码如下:
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;
}
正如它所说,您的代码是同步的。如果你将 UserPrincipal.FindByIdentity
和 PrincipalContext.ValidateCredentials
做的任何事情包装在一个任务中,然后 return 那个,那么你可以让它异步工作。
正如 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;
}
来自MSDN:
以下特征总结了构成异步方法的要素:
- 方法签名包含异步修饰符。
按照惯例,async
方法的名称以 "Async" 后缀结尾。
return 类型是以下类型之一:
Task<TResult>
如果您的方法有一个 return 语句,其中操作数的类型为 TResult
.
Task
如果您的方法没有 return 语句或有一个没有操作数的 return 语句。
Void
如果您正在编写异步事件处理程序。
该方法通常包含至少一个 await 表达式,它标记了等待的异步操作完成之前该方法无法继续的点。同时,该方法被挂起,并将控制 returns 交给该方法的调用者。本主题的下一部分说明了在暂停点发生的情况。
您可以使用 return Task.Run(() => { /* your code here */ })
和 return 和 Task<User>
。然后您可以将此方法称为:
User user = await GetAsyncADUser();
这样就不需要在方法GetAsyncADUser
中使用async
关键字了,但是需要在使用上面这行代码的方法中标记[=11] =]关键字。
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;
}
在此代码块中似乎没有等待等待的异步调用....我的意思是,没有方法调用 returns 任务。
例如,如果方法 UserPrincipal.FindByIdentity()
是一个异步方法,(returns Task<UserPrincipal>
) 那么它可以像这样等待:
UserPrincipal userPrincipal = await UserPrincipal.FindByIdentity();
但是,它不是异步方法,因此没有什么可等待的。您可以在这里做的一件事是将您想要 运行 的代码异步包装在辅助方法中,通过 Task.Run(() => RunMeAsync());
执行该辅助方法并等待您刚刚开始的新任务的结果。
var result = await Task.Run(() => RunMeAsync());
其中 RunMeAsync()
是您想要异步 运行 的辅助方法。
我正在转换身份验证过程以支持异步,VS 2015 IDE 警告我以下消息: 异步方法缺少 'await' 运算符,将 运行 同步... 等...
无论如何,代码连接到 LDAP 存储并验证用户的帐户等... 我用 await 尝试了各种方法,但我只是在这里遗漏了一些东西。我将代码恢复到原来的状态。我将不胜感激任何让它正确支持异步的指导......
代码如下:
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;
}
正如它所说,您的代码是同步的。如果你将 UserPrincipal.FindByIdentity
和 PrincipalContext.ValidateCredentials
做的任何事情包装在一个任务中,然后 return 那个,那么你可以让它异步工作。
正如 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;
}
来自MSDN:
以下特征总结了构成异步方法的要素:
- 方法签名包含异步修饰符。
按照惯例,
async
方法的名称以 "Async" 后缀结尾。 return 类型是以下类型之一:Task<TResult>
如果您的方法有一个 return 语句,其中操作数的类型为TResult
.Task
如果您的方法没有 return 语句或有一个没有操作数的 return 语句。Void
如果您正在编写异步事件处理程序。
该方法通常包含至少一个 await 表达式,它标记了等待的异步操作完成之前该方法无法继续的点。同时,该方法被挂起,并将控制 returns 交给该方法的调用者。本主题的下一部分说明了在暂停点发生的情况。
您可以使用 return Task.Run(() => { /* your code here */ })
和 return 和 Task<User>
。然后您可以将此方法称为:
User user = await GetAsyncADUser();
这样就不需要在方法GetAsyncADUser
中使用async
关键字了,但是需要在使用上面这行代码的方法中标记[=11] =]关键字。
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;
}
在此代码块中似乎没有等待等待的异步调用....我的意思是,没有方法调用 returns 任务。
例如,如果方法 UserPrincipal.FindByIdentity()
是一个异步方法,(returns Task<UserPrincipal>
) 那么它可以像这样等待:
UserPrincipal userPrincipal = await UserPrincipal.FindByIdentity();
但是,它不是异步方法,因此没有什么可等待的。您可以在这里做的一件事是将您想要 运行 的代码异步包装在辅助方法中,通过 Task.Run(() => RunMeAsync());
执行该辅助方法并等待您刚刚开始的新任务的结果。
var result = await Task.Run(() => RunMeAsync());
其中 RunMeAsync()
是您想要异步 运行 的辅助方法。