0

我正在寻找将键值对存储在静态同步字典(.NET 3.5,因此不是 ConcurrentDictionary)中同时能够同时访问它们的最有效方法。

Dictionary.Add(key, value);

if (Dictionary.Count >= 200)
{
       foreach (KeyValuePair<string, Info> pair in Dictionary)
       {
              Info entry = pair.Value;
              StoreInDatabase(entry);
       }

       Dictionary.Clear();
}

这就是问题所在。如果一个用户正在向字典中添加内容,而另一个用户正在访问并存储到数据库中,则会中断。

lock (Dictionary)
{
    //Same Code Above
}

我放了一个锁,它似乎工作正常,但我想知道是否有更有效的方法来做到这一点。它不像我希望的那样有效。我们欢迎所有的建议!

注意:我必须使用 StoreInDatabase 方法来存储值。


修订后的代码:

private static SynchronizedDictionary<string, Info> Dictionary = new SynchronizedDictionary<string, Info>();

...

Dictionary.Add(key, value);

if (Dictionary.Count >= 200)
{
       SynchronizedDictionary<string, Info> temporaryDictionary = new SynchronizedDictionary<string, Info>();
       lock (Dictionary)
       {
            temporaryDictionary = Dictionary;
            Dictionary.Clear();
       }

       lock(temporaryDictionary)
       {
            foreach (KeyValuePair<string, Info> pair in temporaryDictionary)
            {
                  Info entry = pair.Value;
                  StoreInDatabase(entry);
            }
       }
}

这大大提高了性能。谢谢flq!

4

2 回答 2

3

您将锁定数据库操作,与内存中的活动相比需要很长时间

在锁中,您应该复制要存储在数据库中的值并清除字典。然后你可以释放字典,其他一些线程将这些东西写入数据库。

此外,使用一些私有锁定对象以最大程度地减少死锁的可能性可能是有意义的。

于 2012-05-30T13:59:26.700 回答
1

我已经使用 Interlocked 实现了一个线程安全的字典,这是可用的最轻量级的同步机制。

你可以在这里找到源代码。它是为 Fasterflect 编写的,Fasterflect 是一个有助于使反射任务更轻松、更快的库。该代码使用 #ifdefine 有条件地启用 .NET 3.5 的自定义字典,因为我们的基准测试显示 .NET 4.0 ConcurrentDictionary 更快。

正如 flq 指出的那样,在持有锁的同时访问数据库是一个非常糟糕的主意。认真地说,不是你想做的事情。寻找更好的解决方案,例如将需要存储的数据复制到临时数据结构中。

于 2012-05-30T14:39:06.433 回答