1

I want to do a Parallel.ForEach(... ) for the below code snipet, however as there are two function calls - both should happend in the same block, as the second funtion is consuming the value returned by the first function. I don't know who to achive this. Basically I want to convert the below into a Parallel.ForEach(...). Thanks in advance.

       List<Employee> employeeList = GetEmployees();

       foreach (var emp in employeeList)
            {
                var empDetails = GetEmpDetails(emp.EmployeeId);

                ProcessEmployeeDetails(empDetails);
            }

I already tried the below, it is not working:

            Parallel.ForEach(employeeList, emp =>
            {
                var empDetails = GetEmpDetails(emp.EmployeeId);

                ProcessEmployeeDetails(empDetails);

            });
saklo
  • 111
  • 1
  • 11
  • What does not working mean? what happens? can you elaborate on `GetEmpDetails` and `ProcessEmployeeDetails`? – Maor Veitsman Oct 28 '16 at 17:03
  • Are you modifying some common state inside one of this methods? Then the problem is not in Parallel.ForEach, but in a theoretical possibility to run those in parallel at all. – Ilya Chernomordik Oct 28 '16 at 17:06
  • GetEmpDetails(emp.EmployeeId) and ProcessEmployeeDetails(empDetails) are not modifying any common state... so once the detials r returned from GetEmpDetails(emp.EmployeeId), ProcessEmployeeDetails(empDetails) takes those details and work further on saving the details to a new table. – saklo Oct 28 '16 at 17:10
  • Are you getting any errors? – Maor Veitsman Oct 28 '16 at 17:11
  • Please describe then what exactly does not work and how it is supposed to work – Ilya Chernomordik Oct 28 '16 at 17:13
  • I get and exception - the inner exception says: There is already an open DataReader associated with this Command which must be closed first. – saklo Oct 28 '16 at 17:18

1 Answers1

1

It seems that you are using EF connection behind the scenes and that does not seem to be designed for this and executes multiple data retrieval is executed on the same command. You can read more about it here. It has the solution there as well: to enable MARS.

So as far as I can see there is no problem with the Parallel.ForEach, but the problem with some underlying stuff that is not possible to run in parallel out of the box.

P.S. Just to be more clear: you two functions inside the body of the loop will run on the same thread.

Community
  • 1
  • 1
Ilya Chernomordik
  • 27,817
  • 27
  • 121
  • 207
  • yes... I am using Linq to Entity. Thanks for your help. – saklo Oct 28 '16 at 17:34
  • No problem, just try enabling MARS or search for other solutions of that problem if that does not help. You should also be careful with what you do in parallel threads to ensure that they do not edit some unprotected resource or use some other library that is not designed to support multi-threading. – Ilya Chernomordik Oct 28 '16 at 17:36
  • will do so, thanks for you help again. much appreciated. – saklo Oct 28 '16 at 17:38
  • I checked my connection string has this option set to true already. MultipleActiveResultSets=True; – saklo Oct 28 '16 at 18:15
  • I am not a big expert on EF, so cannot help you here unfortunately, but you should ask a separate question about parallel access with EF since you won't likely get an answer for that here. Or check other potential issues with this exception here on SO. P.S. I think server must support MARS as well, not 100% sure on that. Might be other possible solutions to it as wel. – Ilya Chernomordik Oct 28 '16 at 18:18