我有一个静态List<T>
作为缓存对象,被多个线程大量读取。我需要每 5 分钟从数据库刷新一次对象。
问题是,如果我在其中一个线程使用对象时更新对象,则foreach
循环将引发异常。
我试图实现像inUse = true
and之类的标志inUpdate = true
,以及等待标志设置或释放的while循环,但最终它变得太麻烦了,我认为有一个错误会阻止对象被更新。
对于这种情况,我可以使用类似设计模式的东西吗?
编辑:
基于Jim Mischel 的示例,我能够生成以下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication4
{
class Program
{
static Timer g;
static Timer f;
static Timer r;
static Timer l;
static void Main(string[] args)
{
f=new Timer(
o => SetK(new Random().Next(Int32.MinValue, Int32.MaxValue)),
null, 0, 1);
l=new Timer(
o => SetK(new Random().Next(Int32.MinValue, Int32.MaxValue)),
null, 1, 1);
g=new Timer(o => RunLoop(), null, 1000, Timeout.Infinite);
r=new Timer(o => RunLoop(), null, 1001, Timeout.Infinite);
Console.ReadLine();
}
public static void SetK(int g)
{
try {
if(g<0) {
List<int> k=new List<int>(10);
k.Insert(0, g);
k.Insert(1, g);
k.Insert(2, g);
k.Insert(3, g);
k.Insert(4, g);
k.Insert(5, g);
k.Insert(6, g);
k.Insert(7, g);
k.Insert(8, g);
k.Insert(9, g);
SynchronizedCache<Int32>.Set(k);
}
else {
List<int> k=new List<int>(5);
k.Insert(0, g);
k.Insert(1, g);
k.Insert(2, g);
k.Insert(3, g);
k.Insert(4, g);
SynchronizedCache<Int32>.Set(k);
}
}
catch(Exception e) {
}
}
public static void RunLoop()
{
try {
while(true) {
try {
SynchronizedCache<Int32>.GetLock().EnterReadLock();
foreach(var g in SynchronizedCache<Int32>.Get()) {
Console.Clear();
Console.WriteLine(g);
}
}
finally {
SynchronizedCache<Int32>.GetLock().ExitReadLock();
}
}
}
catch(Exception e) {
}
}
}
public static class SynchronizedCache<T>
{
private static ReaderWriterLockSlim
cacheLock=new ReaderWriterLockSlim();
private static List<T> cache=new List<T>();
public static ReaderWriterLockSlim GetLock()
{
return cacheLock;
}
public static void Set(List<T> list)
{
cacheLock.EnterWriteLock();
try {
cache=list;
}
finally {
cacheLock.ExitWriteLock();
}
}
public static List<T> Get()
{
return cache;
}
}
}