2019-11-7-C#-dotnet-线程不安全的弱引用缓存
2023-09-27 14:28:49 时间
title | author | date | CreateTime | categories |
---|---|---|---|---|
C# dotnet 线程不安全的弱引用缓存 |
lindexi |
2019-11-7 9:45:5 +0800 |
2019-11-06 16:58:11 +0800 |
dotnet C# |
很多逻辑都会使用内存做缓存,这样可以提高运行效率。但是有一些逻辑很少会执行,但是如果有执行就是频繁调用。如我写了文本编辑器,在我打开文件的逻辑,将会不断调用正则判断逻辑,而平时编辑很少会调用。如果将这部分的正则逻辑缓存了,那么可以提升打开文件速度,但是在打开文件之后这部分就成为内存垃圾了。本文给大家一个弱引用缓存,也就是在频繁使用时从内存获取,在不使用时会被回收,这样可以提升性能也能减少内存使用
因为作为缓存,如果需要考虑线程安全,那么这部分的逻辑就复杂了。在不考虑线程安全下,开发一个弱引用缓存还是很简单
首先是创建一个字典,这个字典包含弱引用,这样在获取之前可以先从字典获取
private readonly Dictionary<object, WeakReference<object>> _cacheList =
new Dictionary<object, WeakReference<object>>();
在用户获取之前,需要知道,可能内存回收了。所以使用方法是获取或创建,也就是这个方法不能保证只有第一次获取时才创建,而是看内存回收
public T GetOrCreate<T>(object key, Func<T> createFunc)
如果此时可以从内存获取,那么直接返回
if (_cacheList.TryGetValue(key, out var weakReference))
{
if (weakReference.TryGetTarget(out var value))
{
return (T) value;
}
}
如果不能从内存获取,就需要调用方法创建
var t = createFunc();
weakReference = new WeakReference<object>(t);
_cacheList[key] = weakReference;
return t;
所以获取方法如下
/// <summary>
/// 从缓存获取或在没有获取到创建
/// </summary>
public T GetOrCreate<T>(object key, Func<T> createFunc)
{
if (_cacheList.TryGetValue(key, out var weakReference))
{
if (weakReference.TryGetTarget(out var value))
{
return (T) value;
}
}
var t = createFunc();
weakReference = new WeakReference<object>(t);
_cacheList[key] = weakReference;
return t;
}
因为每次给一个 key 也不好用,有一些对象只需要一个类只有存在一个,可以使用类型作为 key 可以再写另一个方法
/// <summary>
/// 从缓存获取或在没有获取到创建
/// </summary>
public T GetOrCreate<T>(Func<T> createFunc)
{
var type = typeof(T);
return GetOrCreate(type, createFunc);
}
这个线程不安全的弱引用缓存所有代码很少,可以直接复制在项目使用
/// <summary>
/// 弱引用缓存
/// </summary>
public class WeakReferenceCache
{
/// <summary>
/// 从缓存获取或在没有获取到创建
/// </summary>
public T GetOrCreate<T>(object key, Func<T> createFunc)
{
if (_cacheList.TryGetValue(key, out var weakReference))
{
if (weakReference.TryGetTarget(out var value))
{
return (T) value;
}
}
var t = createFunc();
weakReference = new WeakReference<object>(t);
_cacheList[key] = weakReference;
return t;
}
/// <summary>
/// 从缓存获取或在没有获取到创建
/// </summary>
public T GetOrCreate<T>(Func<T> createFunc)
{
var type = typeof(T);
return GetOrCreate(type, createFunc);
}
private readonly Dictionary<object, WeakReference<object>> _cacheList =
new Dictionary<object, WeakReference<object>>();
}
此方法是线程不安全的,请不要在多线程下使用此方法,可以通过 线程静态字段 让一个线程有一个实例
本文代码放在 github 欢迎小伙伴访问
相关文章
- 通俗易懂,C#如何安全、高效地玩转任何种类的内存之Span。 给萌新的Flexbox简易入门教程 浅谈Quartz定时任务调度 浅谈JavaScript之Event(上篇) 探索JavaScript数组奥秘 【详解JavaScript系列】JavaScript之函数(一) C# Oracle.ManagedDataAccess 批量更新表数据 VS2015常用快捷键总结
- Word控件Spire.Doc 【超链接】教程(7):在 C#、VB.NET 中的 Word 中创建图像超链接
- Word控件Spire.Doc 转换教程(二十六):在 C#、VB.NET 中将 Word 转换为 EPUB 时添加封面图片
- C#学习记录——统一窗体中控件的字体设置
- c# asp.net mvc API接口安全过滤,api域名过滤,api域名+端口过滤,权限,鉴权
- C#【高级篇】 不安全代码(unsafe)
- C#【控件篇】组件ErrorProvider的使用
- C#,入门教程(42)——各种括号“()[]{}<>“的用法总结
- C#操作快捷方式(获取快捷方式属性、创建快捷方式)
- 在C#中使用Irony实现SQL语句的解析
- C#如何测试代码运行时间
- .Net CCNet C#6.0 自动化编译问题解决
- CRC-16/XMODE X16+X12+X5+1 C#、C和java环境下实现
- C#委托的发布和订阅
- 关于C#中Queue的线程安全问题
- 《C#零基础入门之百识百例》(七十七) 委托事件实例练习2 -- 刘备招亲甘露寺
- C# Dictionary和SortedDictionary简介
- c#事件使用示例详解
- C#.Net下的防抖-Debounce和节流阀-Throttle功能实现