Параллель для структур данных - PullRequest
0 голосов
/ 07 апреля 2020

Я использую параллель.для l oop для данных. Значение, которое изменяется в l oop, является cirNumb, и с этим значением я запрашиваю таблицу данных для заполнения объекта типа IEnumerable<DataRow>. Затем я вызываю экземпляр структуры и должен передать в структуру эту коллекцию IEnumerable<DataRow>. Внутри структуры я использую предыдущую коллекцию для заполнения таблицы данных, но я обнаружил, что иногда результат верен, иногда нет, и я предполагаю, что ошибка в присвоении таблицы данных IEnumerable<DataRow>. Вот некоторый код:

Parallel.For(0, dtCir.Rows.Count, (i, state) =>
{     
    int cirNumb = Convert.ToInt32(dtCir.Rows[i]["no_of_circuits"]);
    IEnumerable<DataRow> dtConnectionSizeLoop = from dtConn in 
                                dtConnectionDatabase.AsEnumerable().AsParallel() 
                                where dtConn.Field<Int32>("no_of_circuits") == cirNumb

    CalculateDC calcDC;
    calcDC = new CalculateDC();
    calcDC.SetParameters(...,dtConnectionSizeLoop,...);
   //do some stuffs
}

Метод struct SetParameters делает некоторые вещи, а также назначает объекту данных объект IEnumerable<DataRow>:

DataTable var_dtConnectionSize = dtConnectionSize.CopyToDataTable();

Может кто-нибудь помочь мне, пожалуйста?

1 Ответ

0 голосов
/ 07 апреля 2020

Классы ADO. NET (DataSet, Datatable et c) не являются поточно-ориентированными, поэтому попытка манипулировать ими из нескольких потоков параллельно без синхронизации может легко повредить их внутреннее состояние. Неправильные результаты, которые вы наблюдаете, могут быть вызваны такой внутренней коррупцией состояния. Поведение объекта с поврежденным внутренним состоянием не определено. Это может вызвать исключения, привести к неверным результатам, вызвать тупик и т. Д. c. Никто не знает на самом деле.

Чтобы защитить объекты от повреждения, вы должны ввести в свой код синхронизацию потоков ( блокировки ). Только один поток будет разрешен для входа за один раз, внутри защищенного блока кода. Это может создать конфликт, если блокировки удерживаются в течение продолжительного промежутка времени, поэтому важно снять блокировку как можно быстрее. Любой код, который не нуждается в защите, должен находиться за пределами защищенной области.

Я мог бы написать несколько примеров, но из названия ваших методов не очевидно, какой метод нуждается в защите, а какой нет. Вполне возможно, что каждая строка вашего кода манипулирует небезопасными объектами, и в этом случае все должны быть защищены, полностью сводя на нет преимущества параллелизма в вашем случае.

...