C# Datatable .AsParallel () AsOrdered () не выдает данные по порядку - PullRequest
0 голосов
/ 13 июля 2020

Я создал таблицу данных и сохранил там некоторые тестовые данные, чтобы увидеть, как AsParallel () с AsOrdered () работает, но когда я тестирую код, я увидел, что не получаю данные ни в одном конкретном c заказ. каждый раз, когда я выполняю код, порядок становится другим. Итак, чего не хватает в моем коде, для которого я не получаю данные по порядку?

см. мой пример кода

DataTable dtTest = new DataTable();
dtTest.Columns.Add("ID",typeof(int));
dtTest.Columns.Add("Name", typeof(string));
dtTest.Columns.Add("Salary", typeof(int));

DataRow dr = dtTest.NewRow();
dr["ID"] = 1;
dr["Name"] = "Rom";
dr["Salary"] = "2000";
dtTest.Rows.Add(dr);

dr = dtTest.NewRow();
dr["ID"] = 2;
dr["Name"] = "David";
dr["Salary"] = "5000";
dtTest.Rows.Add(dr);

dr = dtTest.NewRow();
dr["ID"] = 3;
dr["Name"] = "Samy";
dr["Salary"] = "1200";
dtTest.Rows.Add(dr);


StringBuilder sb = new StringBuilder();
sb.Append("<table>");
sb.Append("<thead><tr><th>ID</th><th>Name</th><th>Salary</th></tr></thead>");
sb.Append("<tbody>");

var htmltables = dtTest.AsEnumerable().AsParallel().AsOrdered().Select(a =>
{
    MessageBox.Show("ID " + a.Field<int>("ID").ToString());

     return   sb.Append("<tr><td>" + a.Field<int>("ID").ToString() 
                + "</td><td>" + a.Field<string>("Name").ToString() 
                + "</td><td>" + a.Field<int>("Salary").ToString()
                +"</td></tr>");
    
}).ToList();

sb.Append("</tbody></table>");

, если кто-нибудь запустит мой тестовый код. net 4.5.2 то должен заметить, что этот порядок идентификаторов становится другим, когда я показываю их в окне сообщения. Я говорю об этой строке MessageBox.Show("ID " + a.Field<int>("ID").ToString());

, поэтому, когда я составляю таблицу внутри параллельного l oop, тогда записи, чей идентификатор равен 1, который когда-нибудь подходит к концу или во второй позиции. Итак, как я могу использовать AsParallel () с AsOrdered () , поскольку идентификатор результата должен быть в порядке?

Я не хочу использовать оператор Lock {} , потому что тогда свобода многопоточности будет конечной sh.

пожалуйста, расскажите мне, как упорядочить данные с помощью многопоточности. спасибо

1 Ответ

2 голосов
/ 13 июля 2020

AsOrdered не означает, что Selects будет выполняться в том же порядке, это означает, что порядок входной последовательности будет сохранен на выходе:

new[] { 1,2,3,4}
    .AsParallel()
    .AsOrdered()
    .Select(i => { Console.WriteLine("in" + i); return i;})
    .ToList(); // resulting list will always have {1,2,3,4} in order, while console output can differ 

Также вы не должны добавлять тот же StringBuilder из нескольких потоков, даже если порядок выполнения будет гарантирован, потому что он не является потокобезопасным. Вы должны накапливать свои результаты и добавлять их. Для начала можно попробовать что-то вроде этого:

var htmltables = dtTest.AsEnumerable()
    .AsParallel()
    .AsOrdered()
    .Select(a =>            
       new StringBuilder()
           .Append("<tr><td>").Append(a.Field<int>("ID").ToString()).Append("</td><td>)
           .Append("<tr><td>").Append(a.Field<int>("Name").ToString()).Append("</td><td>")
           .Append("<tr><td>").Append(a.Field<int>("Salary").ToString()).Append("</td><td>")
    )
    .AsEnumerable();

foreach(var h in htmltables)
{
    sb.Append(h);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...