2012-05-07 35 views
31

Có một câu hỏi liên quan đến an toàn thread với ConcurrentDictionary. Từ API, tôi thấy rằng điều tra viên là an toàn luồng, nhưng tôi không thấy giống nhau đối với các thuộc tính khóa và giá trị. Câu hỏi của tôi là:Là ConcurrentDictionary Keys hoặc giá trị tài sản threadsafe

Có an toàn để lặp lại bộ sưu tập Keys hoặc Values khi có các chủ đề khác sửa đổi đồng thời không?

+1

Các điều tra viên hoạt động khác với Khóa và Giá trị pr operties. Trong khi chúng cung cấp ảnh chụp nhanh thời gian trong từ điển, nội dung được trả về bởi ['GetEnumerator'] (https://msdn.microsoft.com/en-us/library/dd287131.aspx) (cũng được sử dụng trong Truy vấn LINQ sử dụng từ điển làm nguồn) chứa các sửa đổi được thực hiện cho từ điển sau khi 'GetEnumerator' được gọi. –

Trả lời

15

ConcurrentDictionary Đại diện cho một bộ sưu tậpthread-safe khóa-giá trị cặp có thể được truy cập bởi nhiều luồng đồng thời.

Nguồn: MSDN

+4

+1, ngắn gọn! :) Ngoài ra: có, cả hai thuộc tính đều được bảo vệ bằng khóa, những gì bạn sẽ liệt kê là nội dung của từ điển ** tại thời điểm bạn bắt đầu liệt kê ** (vì vậy bạn có thể thấy một khóa, ví dụ, đã được đã xóa khỏi chuỗi khác). –

43

Trong khi tôi làm như tài liệu, tôi có xu hướng để xác minh điều này với một chương trình nhỏ khi nghi ngờ hoặc tôi cảm thấy rằng tôi có thể giả định quá nhiều.

Mã sau đây xác minh rằng bạn thực sự có thể liệt kê các bộ sưu tập giá trị một cách an toàn trong khi thêm hoặc xóa khóa khỏi một chuỗi riêng biệt với chuỗi liệt kê. Điều này sẽ không khiến bộ sưu tập thông thường bị sửa đổi ngoại lệ. Cụ thể hơn, sau đây là một vài trường hợp thử nghiệm

Trường hợp 1: Tiến hành thống kê các giá trị và xóa một phím

Nếu bạn làm theo trình tự sau đây:

  • bắt đầu liệt kê bộ sưu tập giá trị từ một chủ đề
  • xóa khóa khỏi một chuỗi khác mà chúng tôi chưa liệt kê chưa
  • Tiếp tục liệt kê trên chuỗi gốc

Hành vi được quan sát là khóa đã xóa sẽ thực sự được liệt kê vì nó tồn tại trong bộ sưu tập giá trị khi chúng tôi bắt đầu đếm. Không có ngoại lệ sẽ được nâng lên.

Trường hợp 2: Tiến hành thống kê các giá trị và thêm một chìa khóa

  • bắt đầu liệt kê bộ sưu tập giá trị từ một sợi
  • thêm một khóa mới từ một thread khác nhau mà chúng ta chưa liệt kê chưa
  • Tiếp tục liệt kê trên chủ đề ban đầu

Hành vi được quan sát là khóa được thêm sẽ không được liệt kê vì nó d id không tồn tại trong bộ sưu tập giá trị khi chúng tôi bắt đầu liệt kê nó. Không có ngoại lệ sẽ được nâng lên cho dù chúng tôi sử dụng TryAdd hoặc thêm bằng cách chỉ định trực tiếp vào từ điển tức là từ điển [key] = giá trị.

Mã mẫu

Dưới đây là chương trình mẫu đó chứng tỏ cả hai trường hợp:

ConcurrentDictionary<int, int> dictionary = new ConcurrentDictionary<int, int>(); 

// Seed the dictionary with some arbitrary values; 
for (int i = 0; i < 30; i++) 
{ 
    dictionary.TryAdd(i, i); 
} 

// Reader thread - Enumerate the Values collection 
Task.Factory.StartNew(
     () => 
     { 
      foreach (var item in dictionary.Values) 
      { 
       Console.WriteLine("Item {0}: count: {1}", item, dictionary.Count); 
       Thread.Sleep(20); 
      } 

     } 
); 

// writer thread - Modify dictionary by adding new items and removing existing ones from the end 
Task.Factory.StartNew(
     () => 
     { 
      for (int i = 29; i >= 0; i--) 
      { 
       Thread.Sleep(10); 
       //Remove an existing entry 
       int removedValue; 
       if (dictionary.TryRemove(i, out removedValue)) 
        Console.WriteLine("Removed item {0}", removedValue); 
       else 
        Console.WriteLine("Did not remove item {0}", i); 

       int iVal = 50 + i*2; 
       dictionary[iVal] = iVal; 
       Thread.Sleep(10); 
       iVal++; 
       dictionary.TryAdd(iVal, iVal); 
      } 
     } 
); 

Console.ReadKey(); 

Và đây là đầu ra trong chế độ phát hành:

Console output

+1

Muốn microsoft có thể tài liệu này trong MSDN. – user664769

+11

Điều bạn thực sự nói là bộ sưu tập 'Keys' và' Values' là ảnh chụp nhanh của từ điển vào thời điểm bạn nhận được điều tra. Gần giống như họ đã làm một bản sao sâu và đưa nó lại cho bạn để liệt kê hơn. –

Các vấn đề liên quan