Быстрая запись / запись данных в отдельном потоке в C # - PullRequest
8 голосов
/ 12 октября 2010

Мы разрабатываем приложение, которое непрерывно считывает данные с нескольких внешних аппаратных устройств.Скорость передачи данных составляет от 0,5 до 10 МБ / с, в зависимости от конфигурации внешнего оборудования.

Считывание внешних устройств в настоящее время выполняется на BackgroundWorker.Попытка записать полученные данные на диск с помощью того же BackgroundWorker, похоже, не является хорошим решением, поэтому мы хотим поставить в очередь эти данные для записи в файл, а другой поток исключить данные из очереди и выполнитьфайл.Обратите внимание, что для данных будет один производитель и один потребитель.

Мы планируем использовать синхронизированную очередь для этой цели.Но мы подумали, что это колесо, должно быть, было изобретено уже много раз, поэтому мы должны попросить сообщество SO предоставить какой-либо вклад.

Ответы [ 5 ]

3 голосов
/ 12 октября 2010

Я бы сделал то, что делает мрр 888.

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

Аппаратный фоновый рабочий:
Добавляет фрагменты данных с оборудования в Очередь <> .В каком бы формате вы ни использовали его.

Запись фонового рабочего
Анализирует данные, если необходимо, и создает дамп на диск.

Здесь нужно учестьданные с аппаратного обеспечения на диск так быстро, насколько это возможно, важны?
Если да, то я бы устроил тестирование области записи в основном в цикле с циклом ожидания 100 мс или 10 мс в цикле while с проверкой наличия данных в очереди.
Если нет, то я хотел бы, чтобы он либо находился в спящем режиме (исходя из предположения, что скорость, которую вы получаете от вашего оборудования, периодически меняется), и выполнял бы запись на диск только тогда, когда он содержит около 50-60 МБ данных.Я бы подумал сделать это таким образом, потому что современные жесткие диски могут записывать около 60 Мбайт / с (это жесткий диск для настольного компьютера, твой процесс может быть гораздо быстрее), а постоянная запись данных на него небольшими порциями - пустая трата пропускной способности ввода-вывода.

2 голосов
/ 12 октября 2010

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

2 голосов
/ 12 октября 2010

вам может потребоваться очередь

например.код

protected Queue<Byte[]> myQ;
or
protected Queue<Stream> myQ;

//when u got the content try
myQ.Enque(...);

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

// another thread
protected void Loging(){
 while(true){
  while(myQ.Count > 0){
   var content = myQ.Dequeue();
   // save content
  }
  System.Threading.Thread.Sleep(1000);
 }
}
0 голосов
/ 01 ноября 2015

У меня похожая ситуация, в моем случае я использовал асинхронную очередь без блокировки с синхронным объектом LIFO В основном потоки, которые записывают в очередь, устанавливают объект синхронизации в LIFO, в то время как «рабочие» других потоков сбрасывают объект синхронизации в LIFO. Мы зафиксировали количество объектов синхронизации, равных потокам. причина использования LIFO заключается в том, чтобы поддерживать минимальное количество работающих потоков и лучше использовать систему кэширования.

0 голосов
/ 12 октября 2010

Вы пробовали MSMQ

...