Pel*_*red 5 .net c# multithreading
以下代码应该缓存上次读取.这LastValueCache是一个可以被许多线程访问的缓存(这就是我使用共享内存的原因).我可以有竞争条件,但我希望其他线程看到变化LastValueCache.
class Repository
{
public Item LastValueCache
{
get
{
Thread.MemoryBarrier();
SomeType result = field;
Thread.MemoryBarrier();
return result;
}
set
{
Thread.MemoryBarrier();
field = value;
Thread.MemoryBarrier();
}
}
public void Save(Item item)
{
SaveToDatabase(item);
Item cached = LastValueCache;
if (cached == null || item.Stamp > cached.Stamp)
{
LastValueCache = item;
}
}
public void Remove(Timestamp stamp)
{
RemoveFromDatabase(item);
Item cached = LastValueCache;
if (cached != null && cached.Stamp == item.Stamp)
{
LastValueCache = null;
}
}
public Item Get(Timestamp stamp)
{
Item cached = LastValueCache;
if (cached != null && cached.Stamp == stamp)
{
return cached;
}
return GetFromDatabase(stamp);
}
}
Run Code Online (Sandbox Code Playgroud)
该Repository对象被许多线程使用.我不想使用锁定,因为它会影响性能,在我的情况下,这比数据一致性更重要.问题是哪种最小的同步机制能够满足我的需求?也许volatile或单MemoryBarrier中get和set就足够了?
如果这很愚蠢,你不需要投票反对我。
只要告诉我,我就会删除。
但我不遵循这个逻辑。
public void Save(Item item)
{
SaveToDatabase(item);
Item cached = LastValueCache;
if (cached == null || item.Stamp > cached.Stamp)
{
LastValueCache = item;
}
}
Run Code Online (Sandbox Code Playgroud)
您担心内存毫秒数,但在更新缓存之前正在等待写入数据库。
基于公共Item获取印章是关键。
假设数据库写入为 20 毫秒
数据库读取为 10 毫秒
缓存获取和缓存设置各为 2 毫秒
公共无效保存(项目项目)
SaveToDatabase(项目);20 毫秒
项目缓存 = LastValueCache; 2 毫秒
if (cached == null || item.Stamp > cached.Stamp) 1 毫秒
LastValueCache = item; 2毫秒
在 LastValueCache = item; 之前的 23 毫秒内 对 public Item Get(Timestamp stamp) 的任何调用都将访问数据库而不是缓存。
在 LastValueCache = item 之前的 23 毫秒期间;对 public Item LastValueCache get 的任何调用都将获取一个已过时 23 毫秒的值。既定目标是让其他线程看到 LastValueCache - 但他们看到的是陈旧的 LastValueCache。
与删除相同。
您将遭受几次本来可以避免的数据库点击。
你想达到什么目的?
您对此进行过简介吗?
我敢打赌,瓶颈是对数据库的调用。
数据库调用比锁和 MemoryBarrier 之间的差异长 1000 倍。
public void Save(Item item)
{
// add logic that the prior asynchonous call to SaveToDatabase is complete
// if not wait for it to complete
// LastValueCache will possible be replaced so you need last item in the database
// the time for a lock is not really a factor as it will be faster than the prior update
Item cached = LastValueCache;
if (cached == null || item.Stamp > cached.Stamp)
{
LastValueCache = item;
}
// make the next a task or background so it does not block
SaveToDatabase(item);
}
Run Code Online (Sandbox Code Playgroud)
如果您设置 LastValueCache = item; 甚至可以将逻辑更改为仅等待先前的调用;
但你需要以某种方式限制数据库
下一步是缓存最后一个 X 并在 Item Get(Timestamp stamp) 中使用它
数据库调用是您需要优化的
再次您需要分析
之后逻辑将变得更加复杂,但会将数据库调用提供给 BlockingCollection。需要确保最后一个 X 缓存大于 BlockingCollections 大小。如果没有阻塞并等待BC清除。并且您需要使用相同的 BC 进行插入和删除,以便按顺序处理它们。可以变得足够聪明,您只是不插入具有删除的记录。并且不要一次只插入或删除一条记录。
| 归档时间: |
|
| 查看次数: |
578 次 |
| 最近记录: |