2010-06-05 34 views
63

Tiêu chuẩn hiện nay là gì khi cần một bộ sưu tập an toàn chủ đề (ví dụ: Đặt). Tôi có tự đồng bộ hóa hoặc có bộ sưu tập an toàn vốn có không?Bộ sưu tập an toàn chủ đề trong .NET

+6

An toàn cho hoạt động nào? –

+2

@ John, bạn biết đấy, thêm, đọc v.v ... giống như một bộ sưu tập đồng thời của java. – ripper234

+1

bạn nên cập nhật câu hỏi của mình với thông tin này. Nó tạo ra một sự khác biệt lớn mà bạn muốn các bộ sưu tập là chủ đề an toàn cho mọi thứ, so với một bộ sưu tập, ví dụ, luồng chỉ an toàn để chèn. –

Trả lời

94

.NET Framework 4.0 giới thiệu một số bộ sưu tập thread-safe trong System.Collections.Concurrent Namespace:

ConcurrentBag<T>
      Đại diện cho một, bộ sưu tập có thứ tự thread-safe của các đối tượng.

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

ConcurrentQueue<T>
    Đại diện cho một (FIFO) đầu tiên sưu tập trong lần đầu tiên ra thread-safe.

ConcurrentStack<T>
    Đại diện cho một cuối thread-safe trong đầu ra (LIFO) bộ sưu tập.


bộ sưu tập khác trong .NET Framework không phải là thread-safe theo mặc định và cần phải được khóa cho mỗi hoạt động:

lock (mySet) 
{ 
    mySet.Add("Hello World"); 
} 
+3

Bạn có thể thích sử dụng ReaderWriterLockSlim khi tạo bộ sưu tập theo chủ đề an toàn. – SandRock

4

NET 4 cung cấp một bộ sưu tập thread-safe dưới System.Collections.Concurrent

17

Pre .net 4.0 hầu hết các bộ sưu tập trong .Net không phải là chủ đề an toàn. Bạn sẽ phải làm một số công việc cho mình để xử lý đồng bộ hóa: http://msdn.microsoft.com/en-us/library/573ths2x.aspx

Trích dẫn từ bài viết:

Bộ sưu tập các lớp học có thể được thực hiện chủ đề an toàn sử dụng bất kỳ phương pháp sau đây:

Tạo một trình bao bọc an toàn chỉ bằng cách sử dụng phương thức đồng bộ và truy cập bộ sưu tập độc quyền thông qua trình bao bọc đó.

Nếu lớp học không có phương thức Đồng bộ, lấy từ lớp và triển khai phương thức Đồng bộ bằng thuộc tính SyncRoot.

Sử dụng một cơ chế khóa, chẳng hạn như các tuyên bố khóa trong C# (SyncLock trong Visual Basic), về tài sản SyncRoot khi truy cập vào bộ sưu tập .

Sync Root Property
Lock Statement

Object thisLock = new Object(); 
...... 
lock (thisLock) 
{ 
    // Critical code section 
} 

Trong.ròng 4,0 đã giới thiệu System.Collections.Concurrent namespace

Blocking Collection
Concurrent Bag
Concurrent Queue
Concurrent Dictionary
Ordable Partitioner
Partitioner
Partitioner T

+4

Đối tượng bạn đang khóa trên phải là một biến mẫu, nếu không nó không có ý nghĩa bởi vì bạn luôn khóa trên một tham chiếu mới. – Femaref

+1

Điều đó đúng. Đây chỉ là một ví dụ trên trang MSDN về cách sử dụng mã Khóa. – kemiller2002

1

Trong một Ngoài các lớp học rất hữu ích trong System.Collections.Concurrent, một kỹ thuật tiêu chuẩn trong hầu hết -số lần thay đổi-hiếm khi-thay đổi enarios (hoặc nếu có tuy nhiên thường xuyên, nhưng không đồng thời viết) cũng có thể áp dụng cho. Net được gọi là Copy-on-write.

Nó có một vài tính năng mà là mong muốn trong chương trình được đánh giá cao đồng thời:

  • trường hợp đối tượng bộ sưu tập mình đang thay đổi (tức là thread-an toàn, có thể được liệt kê một cách an toàn mà không cần khóa)
  • sửa đổi có thể mất nhiều thời gian như nó muốn, hiệu suất và đồng thời của nội dung đã không bị ảnh hưởng
  • có thể implemented generically để biến bất kỳ cấu trúc dữ liệu mà không phải là thread-safe vào một trong đó là

Giới hạn: Nếu có đồng thời viết, sửa đổi có thể phải được thử lại, do đó, nhiều đồng thời viết có được, hiệu quả kém hơn nó trở thành. (Đó là optimistic concurrency tại nơi làm việc)

bình luận Sửa Scott Chamberlain của nhắc nhở tôi rằng có giới hạn khác: Nếu cấu trúc dữ liệu của bạn là rất lớn, và những thay đổi xảy ra thường xuyên, một bản sao-all-on-viết có thể được ngăn cấm cả về tiêu thụ bộ nhớ và chi phí CPU sao chép liên quan.

+0

Microsoft cung cấp một bộ sưu tập sao chép-ghi-ghi qua NuGet qua [Microsoft.Bcl.Immutable] (https://www.nuget.org/packages/Microsoft.Bcl.Immutable), bạn có thể tìm thêm thông tin [tại đây] (http://blogs.msdn.com/b/bclteam/archive/2012/12/18/preview-of-immutable-collections-released-on-nuget.aspx) –

+0

@ScottChamberlain Cách của họ phức tạp hơn đơn giản của tôi , nhưng chung chung, "sao chép tất cả vào viết" phương pháp tiếp cận, trong đó họ sao chép chỉ là một phần của dữ liệu. Vì vậy, chúng có thể sử dụng được ngay cả khi thay đổi cấu trúc dữ liệu khổng lồ, sẽ không hiệu quả với copy-all-on-write, cả về chi phí CPU sao chép và mức tiêu thụ bộ nhớ để giữ nhiều bản sao đầy đủ trong bộ nhớ. –

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