How to sort a concurrent collection in .NET 4.0
Asked Answered
E

4

9

How to sort a concurrent collection in .NET 4.0 For example I have constructed my ConcurrentBag collection. How can I sort the elements in it?

ConcurrentBag<string> stringCollection;

ConcurrentBag<CustomType> customCollection;
Entail answered 9/8, 2011 at 4:12 Comment(2)
Do you mean that you want a new sorted collection with all the elements at some point in time or do you want it to be sorted all the time and draw from it in that order or something to that effect?Levirate
I wanted to sort it using a method but there isn't any so I have to use LINQ to do the sorting.Entail
E
8

To expand on DSW's answer, you can use the OrderBy on an enumerable.

customCollection.OrderBy(cc => cc.FieldToOrderBy);

You can also do it in descending order:

customCollection.OrderByDescending(cc => cc.FieldToOrderBy);
Exhaust answered 9/8, 2011 at 4:23 Comment(2)
can the collection be altered by another thread while it is being sorted? Or does OrderBy create a new listCecil
OrderBy just sorts a new IEnumerable. The underlying data structure does not change.Gca
R
6

you can use OrderBy method for sorting

and also try this too..

var result = stringCollection.AsParallel().AsOrdered();

for more information check below link

http://msdn.microsoft.com/en-us/library/dd460719.aspx, you can lean how to do complex sorting using PLINQ, e.g:

 var q2 = orders.AsParallel()
       .Where(o => o.OrderDate < DateTime.Parse("07/04/1997"))
       .Select(o => o)
       .OrderBy(o => o.CustomerID) // Preserve original ordering for Take operation.
       .Take(20)
       .AsUnordered()  // Remove ordering constraint to make join faster.
       .Join(
              orderDetails.AsParallel(),
              ord => ord.OrderID,
              od => od.OrderID,
              (ord, od) =>
              new
              {
                  ID = ord.OrderID,
                  Customer = ord.CustomerID,
                  Product = od.ProductID
              }
             )
       .OrderBy(i => i.Product); // Apply new ordering to final result sequence.
Revolting answered 9/8, 2011 at 4:18 Comment(2)
But the objects remain in the concurrent collection. How can I remove the oldest items?Milamilady
Using the .AsParallel() cut my execution time over 1.7M items in half. Great tip.Lynnelle
S
1

Get a list from the collection, sort the list, like:

ConcurrentBag<string> bag = new ConcurrentBag<string>();

var temp = bag.ToList();
temp.Sort();//you can apply a custom sort delegate here

bag = new ConcurrentBag<string>(temp);
Subnormal answered 9/8, 2011 at 4:22 Comment(3)
Man, that's one expensive way to do it!Goldia
Yes I think so, I just added an alternative solution, do you think this should be deleted?Subnormal
Can't see your alternative solution even after refreshing the page. Anyway, it is up to you, but I would leave this answer as is. Don't think it will get voted down since it is not invalid.Goldia
O
1

you can either use PLINQ or you can write implement your own parallel sort function like the one in this article http://www.emadomara.com/2011/08/parallel-merge-sort-using-barrier.html

Oconnell answered 12/8, 2011 at 7:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.