如何通过缓存键锁定? [英] How can I lock by cache key?

查看:144
本文介绍了如何通过缓存键锁定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现一种通用的线程安全的Cache方法,我想知道如何在其中实现锁。

I am trying to implement a generic thread-safe Cache method, and I wonder how I should implement the lock in it.

它应该看起来像像这样:

//private static readonly lockObject = new Object();

public T GetCache<T>(string key, Func<T> valueFactory...)
{

  // try to pull from cache here

  lock (lockObject) // I don't want to use static object lock here because then every time a lock is performed, all cached objects in my site have to wait, regarding of the cache key.
  {
    // cache was empty before we got the lock, check again inside the lock

    // cache is still empty, so retreive the value here

    // store the value in the cache here
  }

  // return the cached value here

}


推荐答案

用于池中的非共享数据


许多池(网络花园)中的每个池都可以有其静态数据。这几天我已经测量到 ConcurrentDictionary< TKey,TItem> 更快,因为他们实现了某种不使用外观的技术,因此他们

For non shared data among pools

When you have many pools (web garden) each pool can have their static data. There I have measure this days that the ConcurrentDictionary<TKey, TItem> is the faster because they have implement some kind of technique that don't use look inside, so they have make it extreme fast.

因此,对于池之间的非共享数据,我建议使用 ConcurrentDictionary< TKey,TItem>

So I suggest the ConcurrentDictionary<TKey, TItem> for non shared data among pools.

在这种情况下,您必须小心自己同步数据,以避免在同一数据上同时发生数据更改。在那里,您可以使用SlimLock或Lock。

In this case you must take care the synchronization of the data him self to avoid concurrent data change on the same the data. There you can use the SlimLock, or a Lock.

现在,当您拥有在池之间共享的资源时,您需要使用互斥锁。例如,如果您尝试从多个线程保存文件,请打开文件以从多个线程更改文件-您需要互斥锁来同步该公共资源

Now, when you have resource that are shared among pools, you need to use mutex. For example if you try to go to save a file from many threads, of open a file for change it from many threads - you need mutex to synchronize that common resource

因此对于公共资源,使用互斥体

Mutex 可以使用密钥进行锁定,以基于该密钥进行锁定-但您不能更改相同的资源!。

So for common resource you use the mutex
Mutex can use a Key to lock to lock base on that key - but you can not change the same resource!.

public T GetCache<T>(string key, Func<T> valueFactory...) 
{
    // note here that I use the key as the name of the mutex
    // also here you need to check that the key have no invalid charater
    //   to used as mutex name.
    var mut = new Mutex(true, key);

    try
    {   
        // Wait until it is safe to enter.
        mut.WaitOne();

        // here you create your cache
    }
    finally
    {
        // Release the Mutex.
        mut.ReleaseMutex();
    }   
}


什么样的锁


我们有两种情况进行锁定。

What kind of lock

we have two case for lock.


  1. 一种情况是,我们在所有线程,所有线程中使用公共资源。公用资源可以是文件,也可以是数据库自身。

  1. One case is when we use common resources in all pools, all threads. Common resource can be a file, or the database its self.

在公用资源中,我们需要使用 mutex 。 / p>

In the common resources we need to use mutex.


  1. 第二种情况是,当我们使用仅对池内部可见的变量时-不同的池无法看到该资源。例如,静态列表<> ,静态字典等。此静态变量,数组只能在池中访问,并且在不同池中它们是不同的。

  1. Second case is when we use variables that are visible only to the inside of a pool - different pools can not see that resources. For example a static List<>, a static Dictionary etc. This static variables, arrays can access only inside the pool and they are not the same across different pools.

在第二种情况下, lock()是最简单,最常用的使用方式。

In this second case, the lock() is the most easy and common way to use.

现在,当我们有一个静态字典并保存了很长时间并且在那里进行过多的读/写操作时,一种避免整个程序等待的更快方法是 ReaderWriterLockSlim

Now, when we have a static dictionary that we keep for long time and make too many reads/writes there, a faster approach to avoid the full program to wait, is the ReaderWriterLockSlim

您可以在此处举一个完整的示例: ReaderWriterLockSlim

you can take a full example from here: ReaderWriterLockSlim

使用ReaderWriterLockSlim,我们可以避免不使用锁需要它们-并且在读取时我们不需要锁定静态值-仅当我们在它们上写入时。因此,对于静态值,我们可以建议使用它们作为缓存。

Using the ReaderWriterLockSlim, we can avoid the locks when we do not need them - and we do not need to lock the static values when we read - only when we write on them. So I can suggest it for static values that we use them as cache.

想象的像是不同运行的程序彼此隔离,但服务于用户的传入请求。每个池都有自己的世界,彼此之间不沟通。每个池都有其初始化,其静态值和寿命。为了在池之间拥有一些公共资源,您需要其他一些第三程序,例如数据库,磁盘上的文件,服务等。

Imaging as if different programs that run isolate each other but serves the incoming requests from users. Each pool have his own world and they are not communicate each other. Each pool have their initialize, their static values, and their life. To have some common resource between pools you need some other third program, like a database, like a file on disk, like a service.

因此,如果您有很多池(网络花园),将它们同步为需要互斥的公共资源。要在您内部同步它们,请使用锁。

So if you have many pools (web garden) to synchronize them for common resource you need mutex. To synchronize them inside you use lock.

IIS应用程序池,工作进程,应用程序域

ASP.NET静态变量的生命周期

这篇关于如何通过缓存键锁定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆