以下代码将从网站调用,因此在非静态类中有一个静态字典对象需要线程安全。基本上,代码的目的是封装逻辑并维护存储在CounterContainer实例中的perfmon计数器的生命周期。构造函数被称为传入instanceName。构造函数需要检查该实例名称的CounterContainer是否已被定义并存储在字典中。如果是这样,它可以(并且必须)使用该实例。如果不是,它会创建一个CounterContainer实例,将其存储在字典中,然后使用该实例。要使用的CounterContainer实例存储在一个非静态成员中,因此线程安全。这是锁定线程安全的正确对象吗?
作为使用静态字典的唯一地方是在构造函数中,它让我觉得在它将被访问期间锁定字典是安全的吗?这是否会导致任何不可预见的问题,如阻塞/死锁?我什么都看不到,但过去并没有太多需要考虑这种事情。我也考虑过lock(this):但我不认为这样会工作,因为它只会锁定被创建的PerformanceCounters的实例,而不是基础的静态字典(所以不会是线程安全的)。
namespace ToolKit
{
using System;
using System.Diagnostics;
using System.Collections.Generic;
public class PerformanceCounters : IPerformanceCounters
{
private static Dictionary<string, CounterContainer> _containers = new Dictionary<string, CounterContainer>();
private CounterContainer _instanceContainer;
public PerformanceCounters(string instanceName)
{
if (instanceName == null) throw new ArgumentNullException("instanceName");
if (string.IsNullOrWhiteSpace(instanceName)) throw new ArgumentException("instanceName");
// Is this the best item to lock on?
lock (_containers)
{
if (_containers.ContainsKey(instanceName))
{
_instanceContainer = _containers[instanceName];
return;
}
_instanceContainer = new CounterContainer(instanceName);
_containers.Add(instanceName, _instanceContainer);
}
}
public void Start()
{
_instanceContainer.AvgSearchDuration.Start();
}
public void FinishAndLog()
{
_instanceContainer.SearchesExecuted.Increment();
_instanceContainer.SearchesPerSecond.Increment();
_instanceContainer.AvgSearchDuration.Increment();
}
}
}
你有没有考虑过使用ConcurrentDictionary类?那么你不必担心它 - 也可以重复到这个问题:http://stackoverflow.com/questions/440957/c-concurrency-locking-and-dictionary-objects – BrokenGlass 2010-09-29 13:07:40
@BrokenGlass:对不起,我错过了,是的,他们几乎完全相同的情况。在没有听说过ConcurrentDictionary类之前,它也被提出来作为对此的回应。 – 2010-09-29 17:30:14