如何锁定词典

本文关键字:锁定 何锁定 | 更新日期: 2023-09-27 18:24:05

我在多线程应用程序中有一个静态字典。class A读取字典,class B从中删除。我想在从字典中删除或读取字典时锁定字典,以防止在并发情况下访问它时出现问题。我怎样才能锁住字典?

    public static Dictionary<string, Thread> DicThreads = new Dictionary<string, Thread>();
    Class A()
    {
     private void MethodA()
    {
if (DicThreads.ContainsKey(key))
       if (DicThreads[key] == null || DicThreads[key].ThreadState == ThreadState.Stopped)
    {
     //--- Do something
    }
    }

    class B
    {
      private void MethodB()
    {
       DicThreads.Remove(key)
    }
}

如何锁定词典

您可以按照pwas的建议使用ConcurrentDictionary。如果要同步现有的词典,请使用lock关键字。

您通常应该使用一个单独的对象进行同步,并且不要将该对象暴露在您的范围之外。这确保了块外的代码不能将同一个对象用于锁并导致冲突。

public static Dictionary<string, Thread> DicThreads = new Dictionary<string, Thread>();
private static object sync = new Object();
Class A() {
  private void MethodA() {
    lock (sync) {
      if (DicThreads.ContainsKey(key)) {
        if (DicThreads[key] == null || DicThreads[key].ThreadState == ThreadState.Stopped) {
          //--- Do something
        }
      }
    }
  }
}
class B {
  private void MethodB() {
    lock (sync) {
      DicThreads.Remove(key)
    }
 }
}

您可以使用lock

lock (DicThreads)
{
   // Any code here is synchronized with other
   // (including this block on other threads)
   // lock(DicThreads) blocks
}

但是,如果您的应用程序中有一个线程字典,那么您可能做错了。请在此处阅读有关基于任务的异步模式(TAP)的全部内容。

Stephen Cleary编写了一个有用的AsyncCollection<T>类。在NuGet上的Nito.AncEx包中提供。

如果您需要一个异步集合——它是一个很好的候选者,那么它实际上需要一个ConcurrentBag/Stack/Queue或其他IProducerConsumerCollection来提供支持状态。

记住,如上所述,您不应该自己管理线程,如问题所示。

使用ConcurrentDictionary<T>