用C#封装一个线程安全的缓存器,达到目标定时更新
错峰缓存,减少数据库IO瓶颈。
using System.Collections.Concurrent;
using Tools;
namespace SpacePhoneAPI.BackTask
{
public class CacheManager<T>
{
private static CacheManager<T>? _instance;
private static readonly object LockObject = new object();
private BlockingCollection<T> buffer;
private int MaxCache = 100;
public delegate Task MyEventHandler(List<T> list);
public event MyEventHandler? UpdateDataEvent;
public CacheManager(int maxCache)
{
MaxCache = maxCache;
buffer = new BlockingCollection<T>(MaxCache);
}
public static CacheManager<T> GetInstance(int maxCache)
{
if (_instance == null)
{
lock (LockObject)
{
if (_instance == null)
{
_instance = new CacheManager<T>(maxCache);
}
}
}
return _instance;
}
public int GetCount()
{
return buffer.Count;
}
/// <summary>
/// 添加数据,触发被动更新
/// </summary>
/// <returns></returns>
public void AddData(T data)
{
buffer.Add(data);
NLogHelper.Debug("debug:" + buffer.Count.ToString());
if (buffer.Count >= MaxCache)
{
UpdateDataEvent?.Invoke(buffer.ToList());
buffer.Clear();
}
}
/// <summary>
/// 主动更新
/// </summary>
/// <returns></returns>
public async Task InitiativeUpdate()
{
await Task.Run(() =>
{
if (buffer.Count > 0)
{
UpdateDataEvent?.Invoke(buffer.ToList());
buffer.Clear();
}
});
}
}
}
扩展方法
public static class ExtendBlockingCollection
{
public static void Clear<T>(this BlockingCollection<T> blockingCollection)
{
if (blockingCollection == null)
{
throw new ArgumentNullException("blockingCollection");
}
while (blockingCollection.Count > 0)
{
T item;
blockingCollection.TryTake(out item);
}
}
}
试用测试:
var cache = CacheManager<int>.GetInstance(10);
cache.UpdateDataEvent += Cache_UpdateDataEvent;
for (int i = 0; i < 100; i++)
{
cache.AddData(i);
Console.WriteLine($"Add:" + i);
}
Console.ReadKey();
async Task Cache_UpdateDataEvent(List<int> list)
{
await Task.Delay(TimeSpan.FromSeconds(1));
string tt = "";
foreach (var item in list)
tt += item + ",";
Console.WriteLine($"Inserted into database:" + tt);
}
文章评论