3

例如我有这个代码:

 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Collections.Immutable;
 using System.Linq;
 using System.Text;
 using System.Threading;
 using System.Threading.Tasks;

 namespace ConsoleApplication2
{
class Program
{
    static void Main(string[] args)
    {
        var lst =new List<int>();
        for (int i = 0; i < 2000000; i++)
        {
            lst.Add(i);
        }

        new Thread(() =>
        {                
            for (int i = 20000001; i < 21000000; i++)
            {
                lst.Add(i);
            }

        }).Start();
        new Thread(() =>
        {
            lst.Where(item =>
                  item > 85200 && item < (50000 * (item + 154896556) * 2 / 1000)
              ).ToList();

        }).Start();

        new Thread(() =>
       {
           for (int i = 21000001; i < 22000000; i++)
           {
               lst.Add(i);
           }

       }).Start();
    }
}
}

我得到了这个异常(附加信息:集合已修改;枚举操作可能无法执行。)因为我在一个线程中发生了变化并在另一个线程中迭代。这是我的问题:如何通过 System.Collections.Immutable.ImmutableList<> 而不是 List<> 重写此代码?

4

2 回答 2

3

为了获得线程安全,您可以使用许多线程安全集合:

  • 阻塞集合
  • 并发字典
  • 并发队列
  • 并发栈
  • 并发包

您甚至可以使用 IProducerConsumerCollection 实现自己的

所有记录在这里: https ://msdn.microsoft.com/en-us/library/dd997305(v=vs.110).aspx

于 2016-03-04T14:37:55.810 回答
1

你确定你想要一个 ImmutableList<> 吗?引用文档:

当您从不可变列表中添加或删除项目时,原始列表的副本与添加或删除的项目一起制作,并且原始列表保持不变。

...

它返回一个添加了对象的新不可变列表,如果它已经包含指定的对象,则返回当前列表。

尝试将您编辑列表的任何实例包装在 lock(list){} 块中,例如:

lock(lst) 
{   
  list.Add(i);
}

当您的代码尝试从 List<> 读取但它被锁定以进行编辑时,您将受到(可能非常轻微的)性能影响,但它应该是线程安全的。

于 2016-03-04T14:31:56.257 回答