1

Interlocked クラスを使用して 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]++;
        }
      }
    }
}

また、Interlocked クラスの ThreadProc のロックを置き換えたい場合は、次のようになります。

public void ThreadProc(object param)
{
  if (m_logStruct.errorCodes.ContainsKey(fullErrCode))
  {
    Interlocked.Increment(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: Argument #1' cannot convert ulong to ref int' (CS1503) (projectx)

修正方法は?

4

1 に答える 1

2

refInterlocked.Increment を呼び出すときに使用する必要があります。

Interlocked.Increment(ref myLong);

またはあなたの場合

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

Interlocked.Increment(ref long)…ということを認識することが重要です。

System.IntPtr の長さが 64 ビットのシステムでのみ、真にアトミックです。他のシステムでは、これらのメソッドは相互に原子的ですが、データにアクセスする他の手段に関してはそうではありません。したがって、32 ビット システムでスレッド セーフにするには、Interlocked クラスのメンバーを介して 64 ビット値にアクセスする必要があります。

http://msdn.microsoft.com/en-us/library/zs86dyzy(v=vs.110).aspx

ちなみに、実際のパフォーマンスの違いは

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

lock(myLock)
{
    m_logStruct.errorCodes[fullErrCode]++;
}

ほとんどのアプリケーションにとって重要ではありません。

アップデート

データ型が署名されていないようです。署名されていない型で Interlocked.Increment を使用するための Jon Skeet のソリューションをご覧ください。

https://stackoverflow.com/a/934677/141172

于 2014-10-16T22:04:30.027 に答える