我打算写一个程序,调用dll,根据用户不同的设定,从服务器读取相应的数据。比如,用户需要设置为SettingOne的A型数据,则调用dll,设置一些参数,调用GetA()。
因为GetA()速度很慢,每次当用户想要A型数据时,需要很长的时间得到返回值,所以想“缓存”以前用过的数据。我在Obj class
里,用了Dictionary<Setting, object> ObjValues
记录之前获取过的数据。当setting一致时,如果字典里没有对应的值,则调用dll,若有,返回对应的值。
这里用Dictionary<Setting, object>
不是最佳的做法吧?因为object
还要被转换成string
, int
, double[]
做余下的处理。
问题是,如何有效的“缓存”多种类型的数据,可以最快地查找到数据?
using System;
using System.Collections.Generic;
namespace test
{
public static class DLL // cannot change the dll
{
public static int Setting1 { get; set; }
public static int Setting2 { get; set; }
public static string Setting3 { get; set; }
public static string GetA() { /* Sleep(10 years) */ return ""; }
public static int GetB() { /* Sleep(10 years) */ return 0; }
public static double[] GetC() { /* Sleep(10 years) */ return new double[] { 0 }; }
}
public class Obj
{
public Dictionary<Setting, object> ObjValues = new Dictionary<Setting, object>();
public void GetValue(Setting setting)
{
DLL.Setting1 = setting.Setting1; DLL.Setting2 = setting.Setting2; DLL.Setting3 = setting.Setting3;
ObjValues[setting] = GetValue(setting.Type); // cache data
}
private object GetValue(ObjType type)
{
switch (type)
{
// loading data from database is assumed to be expensive.
case ObjType.A: return DLL.GetA();
case ObjType.B: return DLL.GetB();
case ObjType.C: return DLL.GetC();
default: return null;
}
}
}
public class Setting
{
public ObjType Type { get; set; }
public int Setting1 { get; set; }
public int Setting2 { get; set; }
public string Setting3 { get; set; }
}
public enum ObjType { A, B, C, D, E }
public class App
{
public static void Main(string[] args)
{
Obj obj = new Obj();
List<Setting> settings = new List<Setting>() { /* SettingOne, SettingTwo, SettingThree ... */};
foreach (Setting setting in settings)
{
if (obj.ObjValues.ContainsKey(setting))
{
Console.WriteLine(obj.ObjValues[setting]); // use the cached data
}
else
{
obj.GetValue(setting);
Console.WriteLine(obj.ObjValues[setting]);
}
}
}
}
}
这个性能没啥好操心的,直接用 Object 转来转去的就行了。当然,考虑提高那么一丁点儿性能,以及加上类型约束以免运行时出错,代码可以这样写:
void Main()
{
Setting<Int32> setting1 = new Setting<int> { Key = "setting1" };
setting1.Set(10);
Console.WriteLine(setting1.Get());
MySetting setting2 = new MySetting { Key = "mysetting" };
setting2.Set("blablabla......");
Console.WriteLine(setting2.Get());
}
public class Setting<T>
{
protected static Dictionary<Setting<T>, T> _cache = new Dictionary<Setting<T>, T>();
public string Key { get; set; } = String.Empty;
public T Get()
{
T val = default(T);
lock(_cache)
_cache.TryGetValue(this, out val);
return val;
}
public void Set(T val)
{
lock (_cache)
_cache[this] = val;
}
public override int GetHashCode()
{
return this.Key.GetHashCode();
}
}
public class MySetting : Setting<String> { }