当商店不支持异步方法时,哪个是 ASPNET Identity 的正确实现?
Which is the proper implementation of ASPNET Identity when the store doesn't support async method?
我是 ASP.NET Identity 2.1 和 async/await 编程的新手。
我想将 ASP.NET Identity 与我的用户存储集成,它不支持 'async' 方法,特别是 Telerik 的 OpenAccess。
在 ASP.NET 标识中,所有 IUserStore
接口(和其他 IXXXStores)仅公开 ~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,不应该像follow吗?
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
方法?
确实 TaskFactory.FromResult
不是正确的异步代码,特别是因为底层 API 正在执行 I/O-bound 操作(这是异步的完美匹配)。但是,没有 一种方法来强制非异步 API 成为异步 API;你只需要让 Telerik 修复他们的 API.
同时,您提到的任何一种方法都可以,但 TaskFactory.FromResult
方法更优越。作为一般规则,您应该避免在 ASP.NET 上使用 Task.Run
,因为它会不必要地干扰线程池。
asynchronous convention 将在任务同步完成时正常工作。当然,该方法是阻塞而不是异步的并不理想,但它会起作用。
我是 ASP.NET Identity 2.1 和 async/await 编程的新手。
我想将 ASP.NET Identity 与我的用户存储集成,它不支持 'async' 方法,特别是 Telerik 的 OpenAccess。
在 ASP.NET 标识中,所有 IUserStore
接口(和其他 IXXXStores)仅公开 ~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,不应该像follow吗?
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
方法?
确实 TaskFactory.FromResult
不是正确的异步代码,特别是因为底层 API 正在执行 I/O-bound 操作(这是异步的完美匹配)。但是,没有 一种方法来强制非异步 API 成为异步 API;你只需要让 Telerik 修复他们的 API.
同时,您提到的任何一种方法都可以,但 TaskFactory.FromResult
方法更优越。作为一般规则,您应该避免在 ASP.NET 上使用 Task.Run
,因为它会不必要地干扰线程池。
asynchronous convention 将在任务同步完成时正常工作。当然,该方法是阻塞而不是异步的并不理想,但它会起作用。