当商店不支持异步方法时,哪个是ASPNET标识的正确实现?

时间:2015-01-04 06:00:09

标签: c# async-await asp.net-identity

我是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方法?

1 个答案:

答案 0 :(得分:2)

TaskFactory.FromResult确实不是正确的异步代码,特别是因为底层API正在执行I / O绑定操作(这是异步的完美匹配)。但是,不是强制非异步API成为异步API的方法;你只需要让Telerik修复他们的API。

与此同时,您提到的任何一种方法都可行,但TaskFactory.FromResult方法更胜一筹。作为一般规则,您应该避免使用ASP.NET上的Task.Run,因为它会不必要地干扰线程池。

当任务同步完成时,asynchronous convention将正常工作。当然,这种方法阻塞而不是异步是不理想的,但它会起作用。