• C#缓存的一点想法及测试


    项目开发中,用到了缓存,其中的一个列表项,可能要多线程处理,就有了下面的想法,具体的问题在代码中有详细说明,见下文。

     1         static void Main(string[] args) {
     2 
     3           
     4 
     5             测试缓存的想法();
     6 
     7             Console.WriteLine("测试结束!");
     8             Console.ReadKey();
     9         }
    10 
    11         /// <summary>
    12         /// 静态的缓存,测试缓存是否存放的指针
    13         /// </summary>
    14         private static MemoryCache memoryCache = MemoryCache.Default;
    15 
    16         private static void 测试缓存的想法() {
    17 
    18             Console.WriteLine("创建一个测试的整型列表:");
    19 
    20             List<int> ints = new List<int>();
    21 
    22             Console.WriteLine("列表中放入{1,2,3}  3个数字");
    23             
    24             ints.Add(1);
    25             ints.Add(2);
    26             ints.Add(3);
    27 
    28             //缓存的策略,10分钟,测试够用了
    29             var policy = new CacheItemPolicy();
    30             policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(10);
    31 
    32             Console.WriteLine("将整型列表放入缓存,缓存10分钟:");
    33             memoryCache.Set("key", ints, policy);
    34 
    35             //不取出更改原有的列表,去除第2个数字
    36             Console.WriteLine("更新原有列表的数据,去除第2个数字,缓存不做处理:");
    37             ints.Remove(2);
    38 
    39             Console.WriteLine("从缓存中取出对应的缓存列表,打印缓存列表项");
    40 
    41             var result = (List<int>)memoryCache.Get("key");
    42 
    43             result.ForEach(r => { Console.WriteLine(r); });
    44 
    45             Console.WriteLine("-----------------第一阶段测试完成------------------------");
    46             Console.WriteLine("");
    47 
    48             Console.WriteLine("直接处理缓存列表项,去除第1个数字,并且没有再次保存至缓存的动作:");
    49             result.Remove(1);
    50 
    51             Console.WriteLine("打印缓存中的列表项:");
    52             //下面这句有没有,打印的结果是一样的
    53             result = (List<int>)memoryCache.Get("key");
    54             result.ForEach(r => { Console.WriteLine(r); });
    55 
    56             Console.WriteLine("");
    57             Console.WriteLine("打印原列表项:");
    58           
    59             ints.ForEach(r => { Console.WriteLine(r); });
    60 
    61             Console.WriteLine("-----------------第二阶段测试完成------------------------");
    62 
    63             Console.WriteLine("直接操作原有的列表项,添加一个数字4:");
    64             ints.Add(4);
    65 
    66             Console.WriteLine("不重新取缓存项,打印缓存中的列表项:");
    67             //下面这句有没有,打印的结果是一样的
    68             result.ForEach(r => { Console.WriteLine(r); });
    69 
    70             Console.WriteLine("");
    71             Console.WriteLine("打印原列表项:");
    72 
    73             ints.ForEach(r => { Console.WriteLine(r); });
    74 
    75             Console.WriteLine("-----------------第三阶段测试完成------------------------");
    76 
    77             /*
    78              * 结论:
    79              * 
    80              * 缓存内部存放的对象的指针,不管是原对象的直接修改,或对缓存项的修改
    81              * 只要缓存的指针没有发生变化,对此对象的修改会同步传导到缓存及原对象的指针
    82              */
    83         }


    其实这个测试并没有什么新意,在.Net中关于对象在内存中的存放位置相关的文章中有明确的说明:

    对象放在托管堆上,对象本身有个指针指向这个托管堆,(虽然这个指针可能会随着GC的运行发生动态调整,但是我们仍然可以当做指针来理解)

    上面测试中的缓存项与原有的列表项,其实指向的是同一块内存,对其中的任何修改,会同时传导到两个对象。理解不了需要看一下.Net的底层的相关知识

    结合C语言的指针理解起来其实更容易一些。

    我想要多线程处理这个缓存列表安全,此时可以换用 ConcurrentBag ,没见过这个对象的同学可以参考MSDN,这是一个多线程操作安全的无序集合。

    此时便可以多线程得到这个缓存项(ConcurrentBag)的 对象,做相应的操作即可,问题解决。

    语言表达能力有限,欢迎批评指正,有砖轻轻拍。

  • 相关阅读:
    Oracle GoldenGate for Sql Server连接ODBC失败的处理方法
    cordova 打包出现transformClassesWithDexForDebug一类错误的解决办法
    mac下cordova的ios-deploy安装问题
    c#截取后台窗口的图片
    命令行--调用ORACLE的SQL语句
    SQL-SERVER 数据库备份 ftp 传到远程服务器 加 restore 数据库 一条龙 附源码
    google map
    怎么根据所给url进行屏幕截屏并保存为图片
    jquery mobile
    研究领域总结(二):稀疏——矩阵补全
  • 原文地址:https://www.cnblogs.com/dhf327/p/4668414.html
Copyright © 2020-2023  润新知