Вы знаете библиотеку массовых / пакетных потоков для C #?

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

Однако я хочу, чтобы наш код поддерживал простой для понимания поток, например:

input = Read();
parsed = Parse(input);
if (parsed.Count > 10)
{
   status = Persist(parsed);
   ReportSuccess(status);
   return;
}
ReportFailure();

Функция, которую я ищу здесь, - это автоматическое выполнение Persist () массово (и, следовательно, асинхронно), но вести себя со своим пользователем, как если бы это было синхронно (пользователь должен блокироваться до тех пор, пока массовое действие не завершится). Я хочу, чтобы разработчик мог реализовать Persist (ICollection).

Я изучал потоковое программирование, с которым не очень хорошо знаком. Я видел одну библиотеку для fbp на C # здесь и немного поиграл с Microsoft Workflow Foundation, но мой впечатление такое, что и то, и другое слишком много для того, что мне нужно. Что бы вы использовали для реализации поведения объемного потока?

Обратите внимание, что я хотел бы получить код, точно такой же, как то, что я написал (простой для понимания и отладки), поэтому решения, которые включают yield или конфигурацию для соединения потоков друг с другом, не подходят для моей цели. Кроме того, цепочка - это не то, что я ищу - я не хочу сначала построить цепочку, а затем запустить ее, мне нужен код, который выглядит так, как будто это простой поток («Сделайте A, сделайте B, если C, то сделайте D»).


person ripper234    schedule 17.09.2008    source источник


Ответы (4)


Распространенная проблема - вместо вызова Persist я обычно загружаю команды (или smt по этим строкам) в класс Persistor, а затем после завершения цикла я вызываю Persistor.Persist, чтобы сохранить пакет.

Всего несколько указателей - если вы генерируете sql, команды, которые вы добавляете в персистор, могут каким-то образом представлять ваши запросы (со встроенными объектами, настраиваемыми объектами или просто строками запроса). Если вы вызываете хранимые процедуры, вы можете использовать команды для добавления материала к фрагменту xml, который будет передан в SP при вызове метода persist.

надеюсь, что это поможет - почти уверен, что для этого есть шаблон, но не знаю названия :)

person JohnIdol    schedule 27.04.2009

Я не знаю, что вам нужно, потому что он основан на sqlserver, но пробовали ли вы взглянуть на SSIS и / или DTS?

person Sklivvz    schedule 17.09.2008
comment
Не совсем. Предположим, у меня есть базовая функциональность PersistBulk (), которая принимает большое количество элементов и сохраняет их (независимо от низкоуровневой реализации). Я хочу предоставить синхронный метод PersistSingleItem (). Ваш ответ не совсем актуален, спасибо. - person ripper234; 18.09.2008

Одна простая вещь, которую вы можете сделать, - это создать MemoryBuffer, куда вы отправляете сообщения, которые просто добавляют их в список и возвращают. Этот MemoryBuffer имеет System.Timers.Timer, который периодически вызывается и выполняет «фактические» обновления.

Одну такую ​​реализацию можно найти на сервере системного журнала (C #) по адресу http://www.fantail.net.nz/wordpress/?p=5, в котором сообщения системного журнала периодически записываются на SQL Server в пакетном режиме.

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

person Khurram Aziz    schedule 03.05.2009

Как насчет использования класса BackgroundWorker для асинхронного сохранения каждого элемента в отдельном потоке? Например:

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;

class PersistenceManager
{
   public void Persist(ICollection persistable)
   {
      // initialize a list of background workers
      var backgroundWorkers = new List<BackgroundWorker>();

      // launch each persistable item in a background worker on a separate thread
      foreach (var persistableItem in persistable)
      {
         var worker = new BackgroundWorker();
         worker.DoWork += new DoWorkEventHandler(worker_DoWork);
         backgroundWorkers.Add(worker);
         worker.RunWorkerAsync(persistableItem);
      }

      // wait for all the workers to finish
      while (true)
      {
         // sleep a little bit to give the workers a chance to finish
         Thread.Sleep(100);

         // continue looping until all workers are done processing
         if (backgroundWorkers.Exists(w => w.IsBusy)) continue;

         break;
      }

      // dispose all the workers
      foreach (var w in backgroundWorkers) w.Dispose();
   }

   void worker_DoWork(object sender, DoWorkEventArgs e)
   {
      var persistableItem = e.Argument;
      // TODO: add logic here to save the persistableItem to the database
   }
}
person Robin    schedule 17.05.2009
comment
Ой! Да, конечно. Извини, что пропустил. Эта строчка кода была у меня в голове, но так и не попала в почту. Сейчас исправлю. Хороший улов, спасибо. - person Robin; 17.05.2009