如何在Singleton中执行昂贵的操作而无需等待?

时间:2013-02-22 21:01:39

标签: c# .net singleton lazy-loading

我创建了一个Singleton模式的类,它包含一些非常昂贵的实例变量(Dictionaries)。

此类用于.NET MVC 4项目。他们关键的是,这个Singleton类中的词典提供的数据是很好,但不是Web应用程序运行所必需的。

换句话说,当我们处理网络请求时,如果字典中的信息可用,则会使用字典中的信息增强该请求,但如果它不可用,那就没问题了。

所以我想做的是找到在Singleton中将数据加载到这些词典中的最佳方法,而不会阻止Web活动,因为它们充满了数据。

我通常会找到一种方法来实现多线程,但过去我在ASP.NET中使用多线程技术阅读并遇到了问题。在.NET 4 / MVC 4中有变化吗?我该怎么做呢?

更新

根据下面的反馈和more research,我现在正在做的是下面,它似乎工作正常。有没有人看到任何潜在的问题?在我的测试中,无论我多少次调用LazySingleton.Instance,构造函数只会被调用一次,并立即返回。我可以立即访问LazySingleton.EXPENSIVE_CACHE,虽然它可能不包含我要查找的值(我使用.Contains()调用在我的应用程序中测试)。所以它似乎在起作用......

如果我只是从单个线程(LazySingleton构造函数)编辑EXPENSIVE_CACHE字典,在我的Web应用程序中读取它时是否需要担心线程安全?

public class LazySingleton
{
    public ConcurrentDictionary<string, string> EXPENSIVE_CACHE = new ConcurrentDictionary<string, string>(1, 80000); // writing to cache in only one thread
    private static readonly Lazy<LazySingleton> instance = new Lazy<LazySingleton>(() => new LazySingleton());

    private LazySingleton()
    {
        Task.Factory.StartNew(() => expensiveLoad());
    }

    public static LazySingleton Instance
    {
        get
        {
            return instance.Value;
        }
    }

    private void expensiveLoad()
    {
        // load data into EXPENSIVE_CACHE
    }
}

1 个答案:

答案 0 :(得分:8)

您可以在任何

上填写现金存储库
  1. Application_Start
  2. 在session_start
  3. 您的网络应用程序事件。
    这样的东西

    <%@ Application Language="C#" %>
    <script runat="server">
        void Application_Start(object sender, EventArgs e) 
        {
            SingletonCache.LoadStaticCache();
        }
    </script>
    

    5月this有用