簡體   English   中英

如何使用ImmutableList <>代替List <>獲得線程安全?

[英]How can use ImmutableList<> instead List<> to gain thread safety?

例如我有此代碼:

 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 <>重寫此代碼?

為了獲得線程安全,可以使用許多線程安全集合:

  • BlockingCollection
  • ConcurrentDictionary
  • ConcurrentQueue
  • ConcurrentStack
  • ConcurrentBag

您甚至可以使用IProducerConsumerCollection實現自己的

全部記錄在這里: https : //msdn.microsoft.com/zh-cn/library/dd997305(v=vs.110).aspx

您確定要使用ImmutableList <>嗎? 引用文檔:

在不可變列表中添加或刪除項目時,原始列表的副本將添加或刪除項目,並且原始列表不變。

...

它返回添加了對象的新的不可變列表,如果已包含指定的對象,則返回當前列表。

嘗試將在其中編輯列表的所有實例包裝在lock(list){}塊中,例如:

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

當您的代碼嘗試從List <>讀取時,您會受到(可能非常輕微的)性能下降,但已被鎖定以進行編輯,但它應該是線程安全的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM