我正在包装AspNet.Identity。但是我对TPL感到有些困惑。
第一个例子:
public virtual async Task<IdentityResult> RemovePasswordAsync(string userId)
{
var user = _store.FindByIdAsync(userId).Result;
if (user == null)
throw new InstanceNotFoundException("user");
user.PasswordHash = String.Empty;
user.SecurityStamp = String.Empty;
return await UpdateAsync(user);
}
public virtual async Task<IdentityResult> UpdateAsync(TUser user)
{
await _store.UpdateAsync(user);
return new IdentityResult();
}
第二个例子:
public virtual Task<IdentityResult> RemovePasswordAsync(string userId)
{
var user = _store.FindByIdAsync(userId).Result;
if (user == null)
throw new InstanceNotFoundException("user");
user.PasswordHash = String.Empty;
user.SecurityStamp = String.Empty;
return UpdateAsync(user);
}
public virtual async Task<IdentityResult> UpdateAsync(TUser user)
{
await _store.UpdateAsync(user);
return new IdentityResult();
}
客户会这样称呼:
result = await _userManager.RemovePasswordAsync(user.Id);
我的第一个问题是:
当客户端调用第二种方法时,工作将从IO线程转移到线程池线程。当RemovePasswordAsync
被调用时,它调用UpdateAsync
具有await关键字的关键字。那么,此时该线程池线程是否已卸载到另一个线程池线程?还是TPL继续使用相同的线程?
我的第二个问题是;构造此async
方法的第一个实现和第二个实现之间的主要区别是什么?
编辑:
这是UserStore
该类的更新方法。(_store.UpdateAsync(user)
)
public Task UpdateAsync(TUser user)
{
if (user == null)
throw new ArgumentNullException("user");
return _userService.UpdateAsync(user);
}
这是UserService
该类的更新方法
public Task UpdateAsync(TUser user)
{
return Task.Factory.StartNew(() => Update(user));
}
我会回答你的第一个问题。
您误会了异步/等待的工作方式。
一种async
方法将同步运行,至少直到它遇到第一个await
声明。到达时await
,有两个选择:
Task
)已经完成,则执行将继续执行当前上下文(即UI线程或ASP.NET请求的上下文)。通过此定义,您的整个代码将在相同的ASP.NET请求的上下文中运行。
_store.UpdateAsync
但是可能会生成ThreadPool线程(例如,使用Task.Run
)。
更新
根据您更新的答案,Update(user)
将在ThreadPool线程上运行。其他所有内容将在当前上下文中运行。
(*)如果没有同步上下文(即控制台应用程序),则该方法主体的其余部分将安排在ThreadPool线程上运行。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句