多个线程增加int

时间:2011-11-30 19:57:29

标签: c# multithreading int

当多个线程尝试增加int时,我遇到了问题。这是我的代码:

private int _StoreIndex;
private readonly List<Store> _Stores = new List<Store>();

public void TestThreads()
{
    _StoreIndex = 0;

    for (int i = 0; i < 20; i++)
    {
        Thread thread = new Thread(() =>
            {
                while (_StoreIndex < _Stores.Count - 1)
                {
                    _Stores[Interlocked.Increment(ref _StoreIndex)].CollectData();
                }
            });
        thread.Start();
    }
}

我希望每次线程执行此代码时int增加1。但事实并非如此。我也尝试过使用lock(new object()),但这也不行。问题是并非所有商店都收集数据,因为(调试时),_StoreIndex就像0,1,1,3,4,5一样。显然会跳过列表中的第二个对象。

我做错了什么?提前谢谢。

3 个答案:

答案 0 :(得分:4)

在你的情况下,我会首先使用TPL来避免手动线程创建和索引的所有这些问题:

Parallel.ForEach(_Stores, (store) => store.CollectData());

答案 1 :(得分:3)

我认为应该纠正:

Thread thread = new Thread(() =>
{
    int index = 0;
    while ((index = Interlocked.Increment(ref _StoreIndex)) < _Stores.Count - 1)
    {
         _Stores[index].CollectData();
    }
});

现在索引是本地的,所以没有干扰,而_StoreIndex仅在一个地方以原子方式使用。

答案 2 :(得分:1)

这不是原子操作:

_Stores[Interlocked.Increment(ref _StoreIndex)].CollectData();

增量是原子的,但是这一行包含的代码多于简单的增量。您可能需要首先对您的indeces进行排序,然后使用线程安全集合来保存您的商店,例如ConcurrentBag,并且可能会考虑使用TPL库和类TaskParallel来执行工作负载。