Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我能摆脱这个读锁吗?_C#_.net_.net 2.0_Locking - Fatal编程技术网

C# 我能摆脱这个读锁吗?

C# 我能摆脱这个读锁吗?,c#,.net,.net-2.0,locking,C#,.net,.net 2.0,Locking,我有以下助手类(简化): (在查找方法中删除了锁(_syncRoot))。问题是这会使用不必要的内存量(这可能不是问题),我可能会使\u查找不稳定,但我不确定该如何应用。() 使用ReaderWriterLock。我相信这会让事情变得更糟,因为被锁定的地区很小 欢迎提出建议 更新: 缓存的值是不可变的。目前正在工作,所以没有什么优雅的东西,我们提出了这个(未经测试) 公共静态类缓存 { 私有静态只读对象_syncRoot=新对象(); 私有静态字典_lookup=新字典(); 公共静态类OneT

我有以下助手类(简化):

(在
查找
方法中删除了
锁(_syncRoot)
)。问题是这会使用不必要的内存量(这可能不是问题),我可能会使
\u查找
不稳定,但我不确定该如何应用。()

  • 使用
    ReaderWriterLock
    。我相信这会让事情变得更糟,因为被锁定的地区很小
  • 欢迎提出建议

    更新:


    缓存的值是不可变的。

    目前正在工作,所以没有什么优雅的东西,我们提出了这个(未经测试)

    公共静态类缓存
    {
    私有静态只读对象_syncRoot=新对象();
    私有静态字典_lookup=新字典();
    公共静态类OneToManyLocker
    {
    私有静态只读对象WriteLocker=新对象();
    私有静态只读列表ReadLockers=new List();
    私有静态只读对象myLocker=new Object();
    公共静态对象GetLock(LockType LockType)
    {
    锁(写器)
    {
    if(lockType==lockType.Read)
    {
    var newReadLocker=新对象();
    锁(myLocker)
    {
    ReadLockers.Add(newReadLocker);
    }
    返回newReadLocker;
    }
    foreach(读卡器中的var读卡器)
    {
    锁(readLocker){}
    }
    返回写器;
    }
    }
    公共枚举锁类型{Read,Write};
    }
    公共静态void Add(类型、字符串值)
    {
    lock(OneToManyLocker.GetLock(OneToManyLocker.LockType.Write))
    {
    _添加(类型、值);
    }
    }
    公共静态字符串查找(类型)
    {
    字符串结果;
    锁(OneToManyLocker.GetLock(OneToManyLocker.LockType.Read))
    {
    _lookup.TryGetValue(类型,输出结果);
    }
    返回结果;
    }
    }
    

    您将需要对读储物柜进行某种清理,但应该是线程安全的,允许一次多次读取,同时也锁定写入,除非我目前在工作中完全遗漏了一些东西,所以没有什么优雅的东西,我想到了这个(未经测试)

    公共静态类缓存
    {
    私有静态只读对象_syncRoot=新对象();
    私有静态字典_lookup=新字典();
    公共静态类OneToManyLocker
    {
    私有静态只读对象WriteLocker=新对象();
    私有静态只读列表ReadLockers=new List();
    私有静态只读对象myLocker=new Object();
    公共静态对象GetLock(LockType LockType)
    {
    锁(写器)
    {
    if(lockType==lockType.Read)
    {
    var newReadLocker=新对象();
    锁(myLocker)
    {
    ReadLockers.Add(newReadLocker);
    }
    返回newReadLocker;
    }
    foreach(读卡器中的var读卡器)
    {
    锁(readLocker){}
    }
    返回写器;
    }
    }
    公共枚举锁类型{Read,Write};
    }
    公共静态void Add(类型、字符串值)
    {
    lock(OneToManyLocker.GetLock(OneToManyLocker.LockType.Write))
    {
    _添加(类型、值);
    }
    }
    公共静态字符串查找(类型)
    {
    字符串结果;
    锁(OneToManyLocker.GetLock(OneToManyLocker.LockType.Read))
    {
    _lookup.TryGetValue(类型,输出结果);
    }
    返回结果;
    }
    }
    

    您需要对读储物柜进行某种清理,但应该是线程安全的,允许一次进行多个读操作,同时也锁定写操作,除非我完全缺少一些东西来完全移除锁(与“无锁”略有不同)当锁几乎被消除,剩下的被巧妙地替换为互锁指令时),您需要确保您的字典是不可变的。如果字典中的项不是不可变的(因此它们有自己的锁),您可能不应该担心字典级别的锁

  • 如果您可以使用它,它是最好、最简单的解决方案
  • 合理且易于调试。(注意:如前所述,它不适合同时添加同一项。如果需要,请考虑双重检查锁定模式-)
  • 如果选择1/2,我不会这么做
    如果您可以使用新的4.0集合-ConcurrentDictionary那里符合您的标准(请参阅和)。

    要完全删除锁(与“无锁”稍有不同,在“无锁”中,锁几乎被消除,剩余的被巧妙地替换为互锁指令),您需要确保字典是不可变的。如果字典中的项不是不可变的(因此它们有自己的锁),您可能不应该担心字典级别的锁

  • 如果您可以使用它,它是最好、最简单的解决方案
  • 合理且易于调试。(注意:如前所述,它不适合同时添加同一项。如果需要,请考虑双重检查锁定模式-)
  • 如果选择1/2,我不会这么做 如果您可以使用新的4.0集合-ConcurrentDictionary,则该集合符合您的条件(请参阅和)。

    或者:

    • 不要使用普通锁,如果查找速度快(字典不快),则使用自旋锁

    • 如果情况并非如此,则使用。这允许多个读卡器和一个写卡器

    或者:

    • 不要使用普通锁,如果查找失败,请转到spinlock
      public static class Cache
      {
          private static readonly object _syncRoot = new object();
          private static Dictionary<Type, string> _lookup = new Dictionary<Type, string>();
      
          public static void Add(Type type, string value)
          {
              lock (_syncRoot)
              {
                  _lookup.Add(type, value);
              }
          }
      
          public static string Lookup(Type type)
          {
              string result;
      
              lock (_syncRoot)
              {
                  _lookup.TryGetValue(type, out result);
              }
      
              return result;
          }
      }
      
      public static void Add(Type type, string value)
      {
          lock (_syncRoot)
          {
              var lookup = new Dictionary<Type, string>(_lookup);
      
              lookup.Add(type, value);
      
              _lookup = lookup;
          }
      }
      
      public static class Cache
      {
          private static readonly object _syncRoot = new object();
          private static Dictionary<Type, string> _lookup = new Dictionary<Type, string>();
      
          public static class OneToManyLocker
          {
              private static readonly Object WriteLocker = new Object();
              private static readonly List<Object> ReadLockers = new List<Object>();
              private static readonly Object myLocker = new Object();
      
              public static Object GetLock(LockType lockType)
              {
                  lock(WriteLocker)
                  {
                      if(lockType == LockType.Read)
                      {
                          var newReadLocker = new Object();
                          lock(myLocker)
                          {
                              ReadLockers.Add(newReadLocker);
                          }
                          return newReadLocker;
                      }
      
                      foreach(var readLocker in ReadLockers)
                      {
                          lock(readLocker) { }
                      }
      
                      return WriteLocker;
                  }
              }
      
              public enum LockType {Read, Write};
          }
      
          public static void Add(Type type, string value)
          {
              lock(OneToManyLocker.GetLock(OneToManyLocker.LockType.Write))
              {
                  _lookup.Add(type, value);
              }
          }
      
          public static string Lookup(Type type)
          {
              string result;
              lock (OneToManyLocker.GetLock(OneToManyLocker.LockType.Read))
              {
                  _lookup.TryGetValue(type, out result);      
              }
      
              return result;
          }
      }