Знаете ли вы пакетную / пакетную библиотеку потоков для C # - PullRequest
1 голос
/ 18 сентября 2008

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

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

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 или конфигурацию для соединения потоков друг с другом, не подходят для моей цели. Также цепочка это не то, что я ищу - я не хочу сначала создавать цепочку, а затем запускать ее, я хочу код, который выглядит так, как будто это простой поток («Do A, Do B, если C, то D» ).

Ответы [ 4 ]

1 голос
/ 27 апреля 2009

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

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

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

0 голосов
/ 17 мая 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
   }
}
0 голосов
/ 03 мая 2009

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

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

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

0 голосов
/ 18 сентября 2008

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

...