我是ASP.NET Identity 2.1的新手,也是async / await编程。
我想将ASP.NET Identity与我的用户存储集成,后者不支持'async'方法,特别是Telerik的OpenAccess。
在ASP.NET标识中,所有IUserStore
接口(和其他IXXXStore)仅公开~Async
方法。看起来他们强烈鼓励异步实现代码运行。不幸的是,Telerik的OpenAccess不支持~Async
版本的方法,所以我必须自己实现它。
我搜索了几个例子,我发现其中许多(不支持~Async
)都是这样的:
public Task<AspNetUser> FindByIdAsync(string userId)
{
if (string.IsNullOrEmpty(userId)) throw new ArgumentException("userId");
var user = this.Context.AspNetUsers.Where(o => o.Id == userId).SingleOrDefault();
return Task.FromResult<AspNetUser>(user);
}
它似乎不是适当的异步代码。当然,按键查找用户可能足够快。但由于它有一个网络I / O,不应该跟着它吗?
public Task<AspNetUser> FindByIdAsync(string userId)
{
if (string.IsNullOrEmpty(userId)) throw new ArgumentException("userId");
return Task.Run(() =>
this.Context.AspNetUsers.Where(o => o.Id == userId).SingleOrDefault()
).ConfigureAwait(false);
}
我不确定只是通过Task.Run
包装同步代码才能使其成为~Async
方法。
上面和下面之间没有什么区别:
public async Task<AspNetUser> FindByIdAsync(string userId)
{
if (string.IsNullOrEmpty(userId)) throw new ArgumentException("userId");
return await Task.Run(() =>
this.Context.AspNetUsers.Where(o => o.Id == userId).SingleOrDefault()
).ConfigureAwait(false);
}
哪种方法可以正常?或者是否有其他方法来实现ASP.NET标识,这些存储不支持本机~Async
方法?
答案 0 :(得分:2)
TaskFactory.FromResult
确实不是正确的异步代码,特别是因为底层API正在执行I / O绑定操作(这是异步的完美匹配)。但是,不是强制非异步API成为异步API的方法;你只需要让Telerik修复他们的API。
与此同时,您提到的任何一种方法都可行,但TaskFactory.FromResult
方法更胜一筹。作为一般规则,您应该避免使用ASP.NET上的Task.Run
,因为它会不必要地干扰线程池。
当任务同步完成时,asynchronous convention将正常工作。当然,这种方法阻塞而不是异步是不理想的,但它会起作用。