C# 使用联锁类进行无锁编程

C# 使用联锁类进行无锁编程,c#,locking,interlocked-increment,C#,Locking,Interlocked Increment,我需要使用联锁类处理C#应用程序中的锁。我有这样的代码: class LogStruct { public Dictionary<string, ulong> domainName; public Dictionary<string, ulong> URL; public Dictionary<string, ulong> domainData; public Dictionary<string, ulong> er

我需要使用联锁类处理C#应用程序中的锁。我有这样的代码:

class LogStruct
{
    public Dictionary<string, ulong> domainName;
    public Dictionary<string, ulong> URL;
    public Dictionary<string, ulong> domainData;
    public Dictionary<string, ulong> errorCodes;

    public LogStruct()
    {
        domainName = new Dictionary<string, ulong> { };
        URL = new Dictionary<string, ulong> { };
        domainData = new Dictionary<string, ulong> { };
        errorCodes = new Dictionary<string, ulong> { };
    }
}

class CLogParser
{
    string domainName = parameters[0];
    string errorCode = matches[1].Value;
    LogStruct m_logStruct;
    ...
    public CLogParser()
    {
         m_logStruct = new LogStruct();
    }
    ...
    public void ThreadProc(object param)
    {
      if (m_logStruct.errorCodes.ContainsKey(fullErrCode))
      {
        lock (m_logStruct.errorCodes)
        {
          m_logStruct.errorCodes[fullErrCode]++;
        }
      }
    }
}
我得到这个错误:

Error CS1502: The best overloaded method match for 
`System.Threading.Interlocked.Increment(ref int)' 
has some invalid arguments (CS1502) (projectx)
这个错误是: 错误CS1503:参数
#1'无法转换
ulong至参考点(CS1503)(项目X)


如何修复它?

在调用Interlocated.Increment时,您需要使用
ref

Interlocked.Increment(ref myLong);
还是你的情况

Interlocked.Increment(ref m_logStruct.errorCodes[fullErrCode]);
重要的是要认识到,
联锁。增量(参考长度)

仅在System.IntPtr为64位长的系统上才是真正的原子。在其他系统上,这些方法相互之间是原子性的,但与访问数据的其他方式无关。因此,为了在32位系统上实现线程安全,必须通过联锁类的成员访问64位值

另一方面,这两种方法之间的实际性能差异

Interlocked.Increment(ref m_logStruct.errorCodes[fullErrCode]);

对于大多数应用程序来说,这将是微不足道的

更新

看起来您的数据类型是未签名的。看一下Jon Skeet的解决方案,该解决方案针对无符号类型使用Interlocked.Increment:


将“ref”添加到呼叫站点。(顺便说一句,这并不是说您的方法的其余部分一定会成功……无锁代码通常很难获得正确的结果,即使是专家也是如此)。@PeterDuniho,这没有帮助啊……我明白了。你用的是“ulong”。只能将带符号整数与Interlocked.Increment一起使用,而不能使用unsigned。
Interlocked.Increment(ref m_logStruct.errorCodes[fullErrCode]);
lock(myLock)
{
    m_logStruct.errorCodes[fullErrCode]++;
}