Jaimesh.2411 Ответов: 4

Как отобразить данные datatable с помощью многопоточности?


Я новичок в многопоточности в C# и запутываюсь в текущей задаче.

Моя задача-читать datatable и отображать datatable в консольном приложении C# с помощью многопоточности.

У меня есть три потока и один datatable, которые имеют 50000 Rors.
Все нити должны начинаться в одно и то же время.
Я хочу :
1-я нить печатает 1-й ряд.
2-я нить печати 2-го ряда.
3-я нить печать 3-го ряда.
снова
1-я нить печатает 4-й ряд.
2-я нить печатает 5-й ряд.
3-я нить печатает 6-й ряд. Продолжайте до последнего ряда.

Как это реализовать???
Есть ли какая-нибудь другая техника для этого????

Что я уже пробовал:

Я тоже пробовал запираться, но у меня ничего не вышло.

4 Ответов

Рейтинг:
28

Dave Kreskowiak

Эта проблема не может быть решена путем нарезания резьбы. Без использования блокировки вы не можете гарантировать порядок выполнения потоков. Вы можете получить такой порядок резьбы, как 1, 2, 3, 1, 3, 2, 3, 1, 2, 1, ...

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

Эта проблема не поддается решению путем нарезания резьбы.


Теперь, если вы пытаетесь показать пользователю 50 000 записей, вы не должны этого делать. Либо отфильтруйте записи до чего-то управляемого, либо реализуйте какой-то механизм подкачки, где вы показываете небольшой блок из большего набора записей.

Я не могу сказать вам, что и как делать, потому что вы ничего не сказали о реальной проблеме, которую пытаетесь решить.


Sascha Lefèvre

5ed

Рейтинг:
2

PureNsanity

Представленное решение на самом деле неосуществимо, потому что система.объект DataTable.Read () не является потокобезопасным. Это означает, что любая попытка чтения с одного и того же считывателя может привести к избыточным, неупорядоченным результатам.

Датируемая безопасность резьбы

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

Реальная проблема в этом примере заключается в чтении данных из большого источника, а затем в их выводе. В случае, если операция чтения является дорогостоящей, оптимальным потоковым решением является использование асинхронного чтения для хранения во временной параллельной коллекции (т. е. ConcurrentBag<t>). После завершения поиска всех данных вы сортируете список, а затем выводите его синхронно. Этот метод требует, чтобы данные содержали информацию, необходимую для сортировки. Если сортировка заказа не требуется, вы можете использовать шаблон производитель-потребитель для повышения производительности вывода.


Рейтинг:
1

Sascha Lefèvre

Если потоки читают только данные из DataTable, вам не нужна блокировка или какая-либо другая синхронизация потоков. Просто передайте DataTable каждому из ваших потоков вместе со значением, которое указывает, в какой строке поток должен начать записывать каждую третью строку в консоль. После запуска все потоки присоединяются к ним, и ваша задача выполнена.

Редактировать: Мое решение игнорирует то, что вы хотите, чтобы строки отображались по порядку. Как сказал Дэйв, с этим требованием задача не поддается многопоточности, потому что тогда потоки должны быть синхронизированы, и не будет никакой пользы от использования одного потока. Таким образом, если должна быть какая-то выгода от многопоточности, то это требование должно быть отброшено. (Но поскольку скорость отображения консоли не так высока, сомнительно, что есть какая-то польза от многопоточности, даже если потоки не синхронизированы.)


Рейтинг:
1

F-ES Sitecore

Если строки должны быть напечатаны по порядку, то вам, вероятно, придется использовать состояния ожидания. В основном это то, что заставляет поток приостанавливаться до тех пор, пока что-то не вызовет состояние, предписывающее потоку продолжать. Таким образом, поток 1 будет читать только строки 1, 4, 7 и т. д. Когда поток 1 запускается, он попадает в состояние ожидания, которое заставляет его ждать, его логика будет такой

1 начало
2 ждать
3 прочитайте следующую строку (1, 4, 7 и т. д.)
4 Если для меня осталось больше строк сбросьте мое состояние ожидания и вернитесь к 2

Поток 2 будет почти идентичен

1 начало
2 ждать
3 прочитайте следующую строку (2, 5, 8 и т. д.)
4 Если для меня осталось больше строк сбросьте мое состояние ожидания и вернитесь к 2

Нить 3 Вы, наверное,уже догадываетесь.

Хитрость в этом заключается в том, чтобы вызвать состояния ожидания, когда начальный процесс вызовет 1, поток один должен будет вызвать два, два вызовут три, а три вызовут одни. Таким образом, все они будут идти последовательно.

Если вам *не нужно * печатать их последовательно, то это легко, это код выше без всех этих вещей состояния ожидания. Google "c# manualresentevent", чтобы получить представление о том, как вы кодируете эти вещи.
возмущение событием