8

tôi có thể sắp xếp ConcurrentDictionary của tôi bằng giá trị như vậy:Sắp xếp một ConcurrentDictionary bởi Value

static ConcurrentDictionary<string, Proxy> Proxies = 
    new ConcurrentDictionary<string, Proxy>(); 

Proxies.OrderBy(p => p.Value.Speed); 

Mà là tuyệt vời, ngoại trừ tôi muốn thiết lập đó mới danh sách tái ra lệnh AS từ điển, hiệu quả sắp xếp các từ điển chính nó hơn là chỉ nhận được một danh sách kết quả của các mục được sắp xếp.

tôi cố gắng làm một cái gì đó như thế này nhưng không có may mắn - từ điển là vẫn có thứ tự sau:

Proxies = new ConcurrentDictionary<string,Proxy>(
    Proxies.OrderBy(p => p.Value.Speed)); 

Nó có vẻ như làm điều đó không có hiệu lực thi hành từ điển. Tôi cũng đã thử đúc kết quả OrderBy vào một var mới nghĩ rằng nó có thể có ảnh hưởng đến đại biểu nhưng vẫn không có may mắn.

Tôi làm cách nào để sắp xếp lại ConcurrentDictionary này và sau đó buộc từ điển trở thành kết quả được sắp xếp lại từ OrderBy?

+0

Nếu bạn cần các thuộc tính truy cập nhanh chóng của một cuốn từ điển, kết hợp với thread-an toàn và sắp xếp liên tục, bạn cần một cái gì đó như một cây B đồng thời. Tôi không tin có sẵn trong .NET. Có lẽ bên thứ ba? Bất kỳ cơ hội bạn chỉ có thể sử dụng OrderBy() khi bạn cần kết quả? – Timo

Trả lời

6

Từ điển đơn giản không phải là các bộ sưu tập được sắp xếp. Chúng chỉ đơn thuần là một bộ sưu tập ánh xạ các khóa tới các giá trị. ConcurrentDictionary không khác gì.

Thay vào đó, bạn cần có SortedConcurrentDictionary (tương tự như SortedDictionary), cấu trúc dữ liệu này không tồn tại.

Còn nếu bạn thực sự yêu cầu "từ điển" được sắp xếp, chúng tôi cần nghe thêm về trường hợp sử dụng của bạn. Đây có phải là hàng đợi ưu tiên giả không? Bạn có thể chỉ cần sử dụng một ConcurrentBag<Proxy> và thực hiện đặt hàng sau khi thực tế?

Nếu bạn cần lấy bộ sưu tập và theo phương pháp song song ở hạ lưu, hãy sử dụng proxy theo thứ tự sắp xếp, tôi khuyên bạn nên tạo một custom Partitioner, có khả năng vay từ MSDN example of an OrderablePartitioner.

+0

Từ điển chỉ được sử dụng để ngăn các giá trị trùng lặp được thêm vào. Trước đây, tôi chỉ đơn giản sử dụng Danh sách và kiểm tra xem các giá trị có tồn tại trước khi thêm hay không. Tôi có thể sử dụng ConcurrentBag nhưng điều đó sẽ yêu cầu sử dụng hai danh sách riêng biệt vì tôi giữ chế độ xem hiển thị chủ động và duy trì proxy trong ListView, cho phép proxy được xem/quản lý/v.v. Việc thực hiện trước đó của Danh sách với các cơ chế khóa đã hoạt động khá tốt cho đến khi tôi đạt đến một lỗi gần đây với các mục rỗng đang có mặt, vì vậy tôi đã thử chuyển sang ConcurrentBag/Dictionary/etc ... – user1111380

+0

Vì vậy, có vẻ như bạn cần đồng thời ' HashSet', mà 'ConcurrentBag' không giống như bạn tìm thấy. Điều này có đồng thời bởi vì một chuỗi khác đến và cập nhật nó không? – user7116

+0

Rgiht, tôi đang sử dụng nhiều chủ đề để kiểm tra proxy và cập nhật danh sách cho phù hợp. – user1111380

0

ConcurrentDictionary, giống như Dictionary, không biết khái niệm sắp xếp, tức là nó không chứa bất kỳ thông tin đặt hàng nào. Kết quả của OrderBy() có một thứ tự cụ thể, nhưng khi được giao cho Proxies thông tin đơn đặt hàng bị mất.

Lưu ý rằng có các triển khai được sắp xếp là IDictionary, cụ thể là SortedDictionarySortedList.

+0

Chắc chắn đây là vấn đề mà Nhóm BCL có thể xem xét? – Eniola

2

Từ điển, đặc biệt là ConcurrentDictionary, về cơ bản không được phân loại.

Nếu bạn cần bộ sưu tập được sắp xếp, bạn sẽ cần phải lưu trữ các giá trị theo một số loại khác, chẳng hạn như SortedDictionary<T,U>.

+0

Tôi hy vọng sẽ sử dụng đồng thời .NET được tích hợp do ConcurrentDictionary cung cấp. Tôi có thể thấy điều này là không thể trong khi cung cấp khả năng được sắp xếp. Quay lại sử dụng các câu lệnh lock() ... cảm ơn. – user1111380

+1

@ user1111380 Chỉ cần cẩn thận - các bộ sưu tập đặt hàng và đồng thời thường xung đột ... Thông thường, (nếu có thể), bạn nên giữ dữ liệu trong bộ sưu tập đồng thời trong khi làm việc trên đó, sau đó trích xuất các mục theo thứ tự cụ thể để hiển thị kết quả , vv –

+0

Nhưng truy xuất các mục theo một thứ tự nhất định, nơi làm việc với bộ sưu tập được đọc nhiều hơn là viết chuyên sâu có thể khá tốn kém. Tôi thấy một trường hợp muốn cập nhật ConcurrentDictionary và có sắp xếp các mục là phần nguyên tử của bản cập nhật. Thay vì phải khởi tạo lại toàn bộ từ điển theo thứ tự sắp xếp mong muốn. Để kết thúc, ConcurrentSortedDictionary hoặc SortedConcurrentDictionary sẽ là một tốt đẹp để có trong BCL. – Eniola

2

Giải pháp là sử dụng SortedSet<T>, được phát hiện sau nhiều giờ nghiên cứu và sửa đổi mã. Một tập hợp được sắp xếp cung cấp duy nhất-Ness của một Dictionary hoặc HashSet, nhưng cũng cho phép sắp xếp - không phải là Dictionary cũng không phải là HashSet cho phép sắp xếp.

+2

Ngoại trừ một SortedSet không đồng thời? Tôi nghĩ rằng có một bộ sưu tập hỗ trợ phân loại và đồng thời là một mặt hàng thiết yếu trong túi công cụ của chúng tôi. Tôi nghĩ chúng ta nên khuyến khích đội BCL xem xét điều này. – Eniola

1

Có lẽ không hiệu quả nếu bạn gọi nó thường trong một lớp học bất biến, nhưng đơn giản:

Imports System.Collections.Concurrent 

Public Class SortedConcurrentDictionary(Of TKey, Tvalue) 
Inherits ConcurrentDictionary(Of TKey, Tvalue) 

    Shadows ReadOnly Property Values As IEnumerable(Of Tvalue) 
     Get 
      If MyBase.Values.Count = 0 Then 
       Return MyBase.Values 
      End If 
      Return From k In Keys Order By k Select Me(k) 
     End Get 
    End Property 
End Class 
+0

Ý tưởng thú vị, nhưng hiệu suất như thế nào? Có vẻ như các phím được sắp xếp theo mọi điều tra của nội dung? – Eniola

+0

@Eniola Bạn nói đúng, như tôi đã nói, "Có thể không hiệu quả". Một phiên bản phức tạp hơn sẽ lưu vào bộ nhớ cache và làm mới bộ nhớ cache khi thay đổi ditionary. – smirkingman

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