1

我正在处理一个具有 peek 性能要求的项目,因此我们需要批量(批处理?)几个操作(例如将数据持久化到数据库)以提高效率。

但是,我希望我们的代码保持易于理解的流程,例如:

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

我在这里寻找的功能是自动让 Persist() 批量发生(并且异步进行),但对其用户的行为就好像它是同步的(用户应该阻止直到批量操作完成)。我希望实现者能够实现 Persist(ICollection)。

我研究了基于流的编程,对此我并不十分熟悉。我在这里看到了一个 C# 中的 fbp 库,并与 Microsoft 的 Workflow Foundation 进行了一些合作,但我的印象是两者都对我的需要来说太过分了。您将使用什么来实现批量流动行为?

请注意,我希望获得与我编写的代码完全相同的代码(易于理解和调试),因此涉及产量或配置以将流相互连接的解决方案不足以满足我的目的。此外,链接 不是我要寻找的 - 我不想先构建一个链然后运行它,我想要看起来好像它是一个简单流程的代码(“Do A, Do B, if C then做 D")。

4

4 回答 4

1

常见问题 - 而不是调用 Persist,我通常将命令(或沿这些行的 smt)加载到 Persistor 类中,然后在循环完成后我调用 Persistor.Persist 来持久化批处理。

只是一些指针 - 如果您正在生成 sql,那么您添加到持久化器的命令可以以某种方式表示您的查询(使用内置对象、自定义对象或只是查询字符串)。如果您正在调用存储过程,则可以使用命令将内容附加到一段 xml,当您调用 persist 方法时,这些内容将传递给 SP。

希望它有所帮助 - 很确定这有一个模式,但不知道名字:)

于 2009-04-27T18:14:17.630 回答
0

我不知道这是否是您需要的,因为它是基于 sqlserver 的,但是您是否尝试过查看SSIS和/或DTS

于 2008-09-17T22:02:36.417 回答
0

如何使用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
   }
}
于 2009-05-17T03:02:29.607 回答
0

您可以做的一件简单的事情是创建一个 MemoryBuffer,您可以在其中推送消息,只需将它们添加到列表中并返回。这个 MemoryBuffer 有一个 System.Timers.Timer 定期调用并执行“实际”更新。

可以在位于http://www.fantail.net.nz/wordpress/?p=5的 Syslog 服务器 (C#) 中找到一个这样的实现,其中 syslog 消息被批量定期记录到 SQL Server。

如果推送到数据库的信息很重要,这种方法可能不太好,如果出现问题,您将丢失 MemoryBuffer 中的消息。

于 2009-05-03T02:38:47.750 回答