对于池之间的非共享数据
当您有许多池(网络花园)时,每个池都可以拥有它们的静态数据。这几天我测量ConcurrentDictionary<TKey, TItem>
到速度更快,因为他们实施了某种不使用内部查看的技术,所以他们让它变得非常快。
所以我建议ConcurrentDictionary<TKey, TItem>
池之间的非共享数据。
在这种情况下,您必须注意自己的数据同步,以避免在同一数据上发生并发数据更改。在那里您可以使用 SlimLock 或 Lock。
池之间的公共资源变化
现在,当您拥有在池之间共享的资源时,您需要使用互斥锁。例如,如果您尝试从多个线程保存文件,或者打开一个文件以从多个线程更改它 - 您需要互斥锁来同步该公共资源
因此,对于使用互斥锁的公共资源,
Mutex可以使用 Key 来锁定基于该键的锁定 - 但您不能更改相同的资源!
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();
}
}
什么样的锁
我们有两个锁盒。
- 一种情况是当我们在所有池、所有线程中使用公共资源时。公共资源可以是文件,也可以是数据库本身。
在公共资源中我们需要使用mutex。
- 第二种情况是当我们使用仅对池内部可见的变量时 - 不同的池无法看到该资源。例如静态 List<>、静态 Dictionary 等。这个静态变量、数组只能在池内部访问,并且它们在不同的池中是不一样的。
在第二种情况下,lock()是最简单和最常用的方法。
比锁还快
现在,当我们有一个长期保存的静态字典并在那里进行太多读/写时,避免整个程序等待的更快方法是ReaderWriterLockSlim
你可以从这里举一个完整的例子:ReaderWriterLockSlim
使用 ReaderWriterLockSlim,我们可以在不需要它们时避免锁定 - 并且我们在读取时不需要锁定静态值 - 只有在我们写入它们时。所以我可以建议我们将它们用作缓存的静态值。
什么是 asp.net 中的池。
就像运行的不同程序相互隔离但为来自用户的传入请求提供服务。每个池子都有自己的世界,彼此之间没有交流。每个池都有它们的初始化、静态值和生命周期。要在池之间拥有一些公共资源,您需要一些其他的第三个程序,比如数据库、磁盘上的文件、服务。
因此,如果您有许多池(网络花园)来同步它们以获得公共资源,则您需要互斥锁。要在内部同步它们,请使用锁。
IIS 应用程序池、工作进程、应用程序域
ASP.NET 静态变量的生命周期