1

what is wrong with this code. It hangs:

public static IEnumerable<Piece> allPiecesList;
private static ConcurrentDictionary<string, Piece> allPiecesCD = new ConcurrentDictionary<string, Piece>();

using (var dc = new MyDataContext())
{
     allPiecesList = dc.PopulateAllPieces("A").ToList();
     Parallel.ForEach(allPiecesList , (piece) => allPiecesCD.TryAdd(piece.Name, piece)); 
}

Note: PopulateAllPieces uses Linq to SQL behind the covers. However, that is all done and we have a IEnumerable before the Parallel part starts.

MyDataContext is a linq to sql data context. Piece.Name is an an accessor property that does not do any computation. Basically, PopulateAllPieces returns a set of records from the database. Each of these records is a 'Piece' object. Piece.Name exposes the column called 'Name' in the database.

Barka
  • 8,764
  • 15
  • 64
  • 91
  • 1
    @JaceRhea I disagree, This example looks ok - ToList is called before the parallel part starts. – Jens Kloster Nov 11 '13 at 17:45
  • @JaceRhea No it's not. The context, or a given query, is never accessed from multiple threads. – Servy Nov 11 '13 at 17:46
  • 2
    @JensKloster It'd be okay even if that wasn't the case, and it'd perform better too. – Servy Nov 11 '13 at 17:46
  • Are you sure you need that concurrent dictionary? Because you're loading it in to memory already using `ToList()`. Perhaps you could just use a dictionary and directly call `ToDictionary()`, albeit the question remains :) – Silvermind Nov 11 '13 at 17:48
  • @Silvermind He might need a `ConcurrentDictionary` because of how it's used after he populates it here, but if not, that may be a preferable option. – Servy Nov 11 '13 at 17:49
  • This is not using entity framework. PopulateAllPieces uses Linq to SQL behind the covers. Either way, that is all done and we have a List before the Parallel part starts. – Barka Nov 11 '13 at 17:49
  • @Servy I agree and the question is ok, but I was just wondering. – Silvermind Nov 11 '13 at 17:50
  • EF is not thread safe. see this http://stackoverflow.com/questions/12827599/parallel-doesnt-work-with-entity-framework . – Thimape Nov 11 '13 at 17:52
  • @Thimape 1) He's not using EF 2) That would be irrelevant, he's not performing any operations that require the underlying query or the objects with in it to handle thread synchronization. – Servy Nov 11 '13 at 17:54
  • 2
    Can you check in the debugger to see how many items get added when it hangs? How many do you have total; is it possible that it just takes a really long time, longer than you expected? – Servy Nov 11 '13 at 17:55
  • What is the point of adding all those items to a single data structure from multiple threads? The `ConcurrentDictionary` will have some locks going most of the time, so you're just adding a lot of overhead. – Jeffrey Sax Nov 11 '13 at 18:18
  • What is the call stack when your code hangs? – svick Nov 11 '13 at 19:55
  • 1
    Try moving `Parallel.Foreach` outside the using statement. If it doesn't use the data context, nothing should change; if it does, you'll get a helpful error message. – Cyanfish Nov 11 '13 at 20:13

0 Answers0