Подходят ли расширения Rx для чтения файла и сохранения в базе данных - PullRequest
1 голос
/ 23 августа 2011

У меня очень длинный файл Excel, который я читаю с помощью EPPlus.Для каждой строки я проверяю, соответствует ли она определенным критериям, и если да, я добавляю строку (объект, представляющий линию) в коллекцию.Когда файл читается, я сохраняю эти объекты в базе данных.Можно ли сделать обе вещи одновременно?Моя идея состоит в том, чтобы иметь коллекцию объектов, которые каким-то образом потреблялись бы потоком, который сохранял бы объекты в БД.В то же время метод Excel Reader будет заполнять коллекцию ... Можно ли это сделать с помощью Rx или есть лучший метод?

Спасибо.

Ответы [ 3 ]

2 голосов
/ 25 августа 2011

Альтернативный ответ - на основе комментариев к моему первому.

Создайте функцию, возвращающую IEnumberable<Records> из EPPlus / Xls - используйте yield return, затем преобразуйте последовательность в наблюдаемое в пуле потоков, и вы 'у нас есть Rx способ иметь производителя / потребителя и BlockingCollection.

function IEnumberable<Records> epplusRecords() 
{
  while (...)
     yield return nextRecord;
}
var myRecords = epplusRecords
   .ToObservable(Scheduler.ThreadPool)
   .Where(rec => meetsCritera(rec))
   .Select(rec => newShape(rec))
   .Do(newRec => writeToDb(newRec))
   .ToArray();
1 голос
/ 24 августа 2011

Кажется, в вашем случае используются данные (IEnumerable), а не данные (IObservable/Rx). Следовательно, я хотел бы предложить LINQ для объектов - это то, что можно использовать для моделирования решения. Нечто подобное показано в коде ниже.

publis static IEnumerable<Records> ReadRecords(string excelFile)
{
  //Read from excel file and yield values
}

//use linq operators to do filtering
var filtered = ReadRecords("fileName").Where(r => /*ur condition*/)
foreach(var r in filtered)
   WriteToDb(r);

ПРИМЕЧАНИЕ. При использовании IEnumerable в этом случае промежуточные коллекции не создаются, и весь процесс выглядит как конвейер.

0 голосов
/ 24 августа 2011

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

Тем не менее, это может быть случай использования plinq. Если EEPlus поддерживает одновременное чтение. Что-то вроде

epplusRecords
   .AsParallel()
   .Where(rec => meetsCritera(rec))
   .Select(rec => newShape(rec))
   .Do(newRec => writeToDb(newRec))
   .ToArray();
...