9

C# でリスト内の要素をインクリメントしようとしていますが、スレッド セーフにする必要があるため、カウントは影響を受けません。

整数に対してこれを行うことができることを知っています:

Interlocked.Increment(ref sdmpobjectlist1Count);

しかし、これは私がこれまでに持っているリストでは機能しません:

lock (padlock)
{
     DifferenceList[diff[d].PropertyName] = DifferenceList[diff[d].PropertyName] + 1;
}

私はこれが機能することを知っていますが、これを行う別の方法があるかどうかはわかりませんか?

4

3 に答える 3

1

David Heffernan が言ったように、ConcurrentDictionary はより良いパフォーマンスを提供するはずです。ただし、複数のスレッドがキャッシュにアクセスしようとする頻度によっては、パフォーマンスの向上が無視できる場合があります。

using System;
using System.Collections.Concurrent;
using System.Threading;

namespace ConcurrentCollections
{
    class Program
    {
        static void Main()
        {
            var cache = new ConcurrentDictionary<string, int>();

            for (int threadId = 0; threadId < 2; threadId++)
            {
                new Thread(
                    () =>
                    {
                        while (true)
                        {
                            var newValue = cache.AddOrUpdate("key", 0, (key, value) => value + 1);
                            Console.WriteLine("Thread {0} incremented value to {1}",
                                Thread.CurrentThread.ManagedThreadId, newValue);
                        }

                    }).Start();
            }

            Thread.Sleep(TimeSpan.FromMinutes(2));
        }
    }
}
于 2013-04-08T21:56:05.320 に答える
1

List<int[]>ではなく aを使用List<int>し、リスト内の各要素を単一項目の配列にすると、Increment(ref List[whatever][0])それをアトミックにすることができます。定義した場合、ストレージ効率をわずかに改善できます

class ExposedFieldHolder<T> {public T Value;}

次に、 aList<ExposedFieldHolder<int>>を使用し、ステートメントを使用Increment(ref List[whatever].Value)してインクリメントを実行しました。ref組み込み型が項目を として公開する手段を提供するか、派生クラスがそのような機能を提供するために内部への十分なアクセスを許可する場合、物事はさらに効率的になります。ただし、そうではないため、独自のコレクション型を最初から定義するか、[配列またはラッパー クラスを使用して]独自のクラス オブジェクトに各項目をカプセル化する必要があります。

于 2013-04-08T22:10:36.797 に答える