c# - .NET ConcurrentDictionary GetOrAdd 方法可以调用异步方法吗?

标签 c# .net asynchronous async-await concurrentdictionary

<分区>

我正在考虑使用 ConcurrentDictionary保存一些来自慢速源(例如数据库)的缓存数据。

对数据库的调用是async .那么,如果字典中不存在该项目,是否可以让并发字典调用异步方法?

例如:

const int userId = 1;
var cachedUsers = new ConcurrentDictionary<int, Task<User>>();
var user = await cachedUsers.GetOrAdd(userId, val => GetSlowDbResultAsync(userId, cancellationToken));

所以上面的伪代码试图做的是:

  • 用户 #1 是否存在于 C-Dict 中?
  • 是的,好的,使用它。
  • 不,从 Db 中获取用户 #1 并将其保存在缓存中。

所以 - 通过将 Task<User>进入并发字典的“值”(对于键/值):

  • 可以吗?
  • 我上面写的代码是否可以接受,或者我只是滥用了 async/await/c# 的所有神圣内容

注意事项:

本题为inspired from my question on twitter .
这类似于 previous question I asked但没有得到太多关注。

最佳答案

尝试写一个扩展方法怎么样,比如:

class Extension
{
    public static User Get(this ConcurrentDictionary<int, User> conDict, int userID)
    {
        User user = null;
        if (!conDict.TryGetValue(userID, out user))
        {
            user = GetSlowDbResultAsync(userId, cancellationToken)
           conDict.TryAdd(userID, user);
        }

        return user;
    }
}

关于扩展方法的更多信息,请查看此article .

关于c# - .NET ConcurrentDictionary GetOrAdd 方法可以调用异步方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47026930/

相关文章:

c# - 我应该如何从 .NET 4.0 中的延续任务传播任务异常?

.net - Hook Entity Framework 中的对象加载事件?

javascript - Node js中Promise是同步还是异步

c# - 从引用的项目发布非托管 DLL

c# - .Net/WinForms .Net 4.0 的对接/ float 库

c# - Winforms 在文本框上禁用键盘输入但保持文本框启用

node.js - Sequelize getter 方法中的异步表查询

c# - 从 CLSID 动态加载 ActiveX 控件

c# - 通过使用 tryparse 而不是 parse 来避免 try-catch

java - 调用执行异步任务的方法的本地实例的垃圾收集