Share via

PLINQ .AsParallel().ForAll throwing error - Index was out of range

T.Zacks 3,996 Reputation points
2021-06-08T18:27:51.73+00:00

first i compose the LINQ query this way which worked properly without any error. here is my code

(from bk in Brokers.AsParallel()
 from prd in Periods.AsParallel()
 from _dsDb in dsDb.Tables[0].AsEnumerable().AsParallel()
 join _dtMain in dtMain.AsEnumerable().AsParallel()

 on new
 {
     val1 = _dsDb.Field<int>("ParentID"),
     val2 = _dsDb.Field<int>("ID"),
     val3 = _dsDb.Field<string>("Section"),
     val4 = _dsDb.Field<string>("LineItem"),
     val5 = _dsDb.Field<string>("DisplayInCSM")
 }
 equals new
 {
     val1 = _dtMain.Field<int>("ParentID"),
     val2 = _dtMain.Field<int>("ID"),
     val3 = _dtMain.Field<string>("Section"),
     val4 = _dtMain.Field<string>("LineItem"),
     val5 = _dtMain.Field<string>("DisplayInCSM")
 }

 where _dsDb.Field<string>("RowType") == "LineItem"
 && _dsDb.Field<int>("ParentID") == ParentID
 && _dsDb.Field<int>("ID") == ID
 && _dsDb.Field<string>("Broker") == bk.BrokerCode &&

 _dtMain.Field<string>("Type") == "Consensus"
 && _dtMain.Field<int>("ParentID") == ParentID
 && _dtMain.Field<int>("ID") == ID
 && _dtMain.Field<string>("Section") == Section
 && _dtMain.Field<string>("LineItem") == LineItem
 && _dtMain.Field<string>("DisplayInCSM") == DisplayInCSM

 select new { _dsDb, _dtMain, bk, prd }).ToList()
    .ForEach(x =>
    {
        x._dtMain.SetField("B_" + x.bk.BrokerCode + "_" + x.prd, (x._dsDb.Field<decimal?>(x.prd ?? "").ToString()));
        x._dtMain.SetField("file_date", (x._dsDb.Field<string>("Revise Date")));
    });

The moment i i use .AsParallel().ForAll() then program throwing error
Index was out of range. Must be non-negative and less than the size of the collection.

This way i use .AsParallel().ForAll() please review my code and tell me what is my mistake in code for which i am getting error.
how to fix the problem

(from bk in Brokers.AsParallel()
 from prd in Periods.AsParallel()
 from _dsDb in dsDb.Tables[0].AsEnumerable().AsParallel()
 join _dtMain in dtMain.AsEnumerable().AsParallel()

 on new
 {
     val1 = _dsDb.Field<int>("ParentID"),
     val2 = _dsDb.Field<int>("ID"),
     val3 = _dsDb.Field<string>("Section"),
     val4 = _dsDb.Field<string>("LineItem"),
     val5 = _dsDb.Field<string>("DisplayInCSM")
 }
 equals new
 {
     val1 = _dtMain.Field<int>("ParentID"),
     val2 = _dtMain.Field<int>("ID"),
     val3 = _dtMain.Field<string>("Section"),
     val4 = _dtMain.Field<string>("LineItem"),
     val5 = _dtMain.Field<string>("DisplayInCSM")
 }

 where _dsDb.Field<string>("RowType") == "LineItem"
 && _dsDb.Field<int>("ParentID") == ParentID
 && _dsDb.Field<int>("ID") == ID
 && _dsDb.Field<string>("Broker") == bk.BrokerCode &&

 _dtMain.Field<string>("Type") == "Consensus"
 && _dtMain.Field<int>("ParentID") == ParentID
 && _dtMain.Field<int>("ID") == ID
 && _dtMain.Field<string>("Section") == Section
 && _dtMain.Field<string>("LineItem") == LineItem
 && _dtMain.Field<string>("DisplayInCSM") == DisplayInCSM

 select new { _dsDb, _dtMain, bk, prd }).AsParallel()
    .ForAll(x =>
    {
        x._dtMain.SetField("B_" + x.bk.BrokerCode + "_" + x.prd, (x._dsDb.Field<decimal?>(x.prd ?? "").ToString()));
        x._dtMain.SetField("file_date", (x._dsDb.Field<string>("Revise Date")));
    });

Getting error when i add AsParallel with ForAll

.AsParallel()
        .ForAll(x =>
        {
            x._dtMain.SetField("B_" + x.bk.BrokerCode + "_" + x.prd, (x._dsDb.Field<decimal?>(x.prd ?? "").ToString()));
            x._dtMain.SetField("file_date", (x._dsDb.Field<string>("Revise Date")));
        });

Please help me to fix the problem. thanks

Developer technologies | C#
Developer technologies | C#

An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.

0 comments No comments

Answer accepted by question author

Timon Yang-MSFT 9,611 Reputation points
2021-06-09T06:48:03.913+00:00

It is mentioned in the documentation of DataTable Class:

This type is safe for multithreaded read operations. You must synchronize any write operations.

For Datatable, parallel writing will cause many problems, so I suggest not to do this.

The explanation in this link is more detailed and easier to understand.

Is Parallel.forEach(DataTable.AsEnumerable() thread safe


If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

Was this answer helpful?

1 person found this answer helpful.
0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.