从AppDomain.CurrentDomain.SetData()获取密钥

时间:2014-03-17 09:23:40

标签: c# appdomain

我使用AppDomain SetData()GetData()在C#中实现了一个非常简单的对象缓存(以减少不经常更改的数据的DB调用次数):

class Program
{
    static void Main(string[] args)
    {
        List<string> users = (List<string>)GetUserList();

        Console.ReadKey();
    }

    private static object GetUserList()
    {
        var users = AppDomain.CurrentDomain.GetData("GetUserList");

        if (null == users)
        {
            users = new List<string>() { "apple", "banana" }; // dummy db results
            AppDomain.CurrentDomain.SetData("GetUserList", users); 
        }

        return users;
    }
}

我现在想要实现一个简单的PurgeCache()方法迭代我的CurrentDomain中的keys并将值设置为null。

我该怎么做呢?


修改

根据Knaģis's回复,我提出了以下内容。

ObjectCache.cs

class ObjectCache
{
    private const string CacheName = "ObjectCache";

    private static Dictionary<String, Object> Load()
    {
        Dictionary<string, object> myObjectCache = AppDomain.CurrentDomain.GetData(CacheName) as Dictionary<string, object>;
        if (null == myObjectCache)
        {
            myObjectCache = new Dictionary<string, object>();
            AppDomain.CurrentDomain.SetData(CacheName, myObjectCache);
        }
        return myObjectCache;
    }

    private static void Save(Object myObjectCache)
    {
        AppDomain.CurrentDomain.SetData(CacheName, myObjectCache);
    }

    public static void Purge()
    {
        Dictionary<string, object> myObjectCache = ObjectCache.Load();
        myObjectCache.Clear();
        ObjectCache.Save(myObjectCache);
    }

    public static void SetValue(String myKey, Object myValue)
    {
        Dictionary<string, object> myObjectCache = ObjectCache.Load();
        myObjectCache[myKey] = myValue;
        ObjectCache.Save(myObjectCache);
    }

    public static Object GetValue(String myKey)
    {
        Dictionary<string, object> myObjectCache = ObjectCache.Load();
        return myObjectCache.ContainsKey(myKey) ? myObjectCache[myKey] : null;
    }
}

Program.cs - 用法

class Program
{
    static void Main(string[] args)
    {
        List<string> users = GetUserList<List<string>>();

        ObjectCache.Purge(); // Removes Cache

        Console.ReadKey();
    }

    private static T GetUserList<T>()
    {
        var users = ObjectCache.GetValue("GetUserList");

        if (null == users) // No Cache
        {
            users = new List<string>() { "adam", "smith" }; // Dummy DB Results
            ObjectCache.SetValue("GetUserList", users);
        }

        return (T)users;
    }
}

1 个答案:

答案 0 :(得分:3)

AppDomain.GetData不应用于缓存目的。而是使用像System.Runtime.Caching这样的解决方案。或者只是static ConcurrentDictionary会更好。

如果您坚持使用AppDomain存储值,则不应删除其中的所有内容 - 它会存储.NET框架正常运行所需的信息。

将值存储在AppDomain对象内的字典中,或者自己保存一个键列表。

使用静态字典的简单内存缓存(第二种方法是针对带有显式锁的.NET 2.0 - 注意这是非常简单的解决方案,有更好的锁定替代方法):

using System;
using System.Collections.Concurrent;

namespace YourNamespace
{
    public static class ObjectCache
    {
        private readonly static ConcurrentDictionary<string, object> Data = new ConcurrentDictionary<string, object>();

        public static void SetValue(string key, object value)
        {
            Data[key] = value;
        }

        public static object GetValue(string key)
        {
            object t;
            if (!Data.TryGetValue(key, out t))
                return null;
            return t;
        }

        public static void Purge()
        {
            Data.Clear();
        }
    }

    public static class ObjectCache2
    {
        private readonly static Dictionary<string, object> Data = new Dictionary<string, object>();

        public static void SetValue(string key, object value)
        {
            lock (Data)
                Data[key] = value;
        }

        public static object GetValue(string key)
        {
            object t;
            lock (Data)
            {
                if (!Data.TryGetValue(key, out t))
                    return null;
            }
            return t;
        }

        public static void Purge()
        {
            lock (Data)
                Data.Clear();
        }
    }
}