从AppDomain.CurrentDomain.SetData()中获取键

本文关键字:获取 AppDomain CurrentDomain SetData | 更新日期: 2023-09-27 17:50:38

我在c#中使用AppDomain SetData()GetData()实现了一个非常简单的对象缓存,像这样(以减少对不经常更改的数据的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 - Usage

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;
    }
}

从AppDomain.CurrentDomain.SetData()中获取键

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();
        }
    }
}