多线程应用程序和Threadsafe列表

时间:2016-07-27 08:59:36

标签: c# multithreading

我一直在多线程应用程序中工作,我仍然试图找到最好/最有效的方法来处理被多个线程使用和更改的List。

我已经看到为一个List写一个Threadsafe类并不是最好的选择,说实话,我发现所有锁定都有些混乱。

我已经考虑将其转换为ConcurrentDictionary,因为我一直在使用它们,它们似乎表现得非常好。

但是,我尝试了不同的方法,并希望听到一些意见,如果它不是一个好的选择:

if(MyList.Count > 0)
{
    MyStruct[] Example = null;
    Example = new MyStruct[MyList.Count];
    MyList.CopyTo(Example, 0);

    foreach(MyStruct B in Example)
       //Code here
}

这只是我尝试过的,似乎无需在其他任何地方进行更改。我不确定我是否应该这样做,这就是为什么我在寻找一些意见

2 个答案:

答案 0 :(得分:1)

不,这不是线程安全的。

为简单起见,考虑两个线程。

  1. 主题A创建包含10个项目的列表
  2. 线程B看到列表中有10个项目,并为10个项目
  3. 创建一个数组
  4. 主题A将一个项目添加到列表中,因此它现在有11个项目
  5. 线程B在CopyTo上崩溃,因为阵列不够大
  6. 这是可能发生的最严重的事情之一。

    不要随意乱用多线程。它很乱,很危险,你会留下很多难以重现和修复的错误。除非明确说某些东西是线程安全的,否则不要假设任何线程安全。多线程的强制启动:http://www.albahari.com/threading/

    通常的清单如下:

    1. 首先是否需要多线程?
    2. 你确定肯定吗?
    3. 是否有完全符合您需要的线程安全类?
    4. 您是否可以使用保证不会死锁的简单一致的锁定架构?
    5. 您是否确定需要在多个线程之间共享该对象?
    6. 说真的,多线程很难。您是否可以使用在线程之间显式传递的不可变数据,而不是使用共享可变状态?
    7. 找到最简单的方法来处理线程之间的同步。
    8. 它够好吗?好的,停下来。
    9. 这还不够好?考虑数据共享的替代方法。
    10. 如果您仍然在共享资源上有瓶颈,请考虑无锁编程。 这比基于锁的同步要困难得多。确保你知道自己在做什么。即使是设计C#/ .NET的人也非常担心无锁编程。甚至是Raymond Chen,也就是软件工程的Chuck Norris。有狮子。您需要完全理解所有现有和无法保证的内容,以及平台上的安全性以及所有平台的共同点。

答案 1 :(得分:0)

您不需要创建结构数组。只需将CopyTo与另一个List或ToArray一起使用。

另外,您可以使用BlockingCollection,这对于Producer Consumer操作来说是线程安全的。 https://msdn.microsoft.com/en-us/library/dd267312(v=vs.110).aspx