【问题标题】:Thread management console program with continuous (endless) tasks具有连续(无尽)任务的线程管理控制台程序
【发布时间】:2013-11-13 20:02:33
【问题描述】:

我是线程新手,所以请耐心等待。

我的数据库中有数万行。每行代表需要通过 Internet 完成的工作。我读取了一个数据行,我做了一些与网络相关的工作(甚至可能需要几秒钟到几分钟的时间),然后我抓取下一个数据行(我的 C# 应用程序使用控制台,而不是 GUI)。正如你所料,我想同时做这些工作。

我研究了这个主题,并认为我会使用 BackgroundThreads,但如果我理解正确people suggest,那么在控制台应用程序中使用它们是没有意义的。

我认为我不应该使用任务,因为我的每个“任务”都将由一个线程表示。

所以我想我会将 ThreadPool 与常规线程一起使用。

为了简单起见,我只想保持恒定数量的线程(当一个线程完成时产生新的线程),直到我用完了要做的事情(然后我等待数据 - 通常是很多数据 - 到达数据库并产生线程)。我需要知道线程何时结束,因为我必须生成一个新线程并更新包含它正在使用的数据的数据库行。为了使线程和数据库保持同步,我可能必须在检索时用某种线程 id 标记数据库行,然后在线程结束时标记该行(成功/失败)。 this solution(尝试在线程委托中捕获)是否足以确保线程已经结束(以及它是否成功或抛出异常)?

我不确定如何“等待”第一个线程结束 - 不是全部,也不是特定线程。

我还认为我不想提前读取太多数据(并可能等待线程释放),因为可能有其他程序使用同一个数据库做同样的事情。

任何想法表示赞赏!

【问题讨论】:

  • 由于你的瓶颈将是网络而不是 CPU,你不应该使用任务。这可能是使用 .NET 4.5 的 async/await 功能的好地方

标签: c# database multithreading


【解决方案1】:

只需使用Parallel.ForEach 即可:

Parallel.ForEach(rows, row => ProcessRow(row));

如果您需要指定最大并行化程度,因为自动分区器碰巧使用了太多线程池线程,那么您可以这样指定:

Parallel.ForEach(rows, new ParallelOptions() { MaxDegreeOfParallelism = 5 }
    , row => ProcessRow(row));

【讨论】:

  • 我不确定如何不断地向它提供数据。你建议我以某种方式缓冲数据?读取一部分,执行 Parellel.ForEach,等待它完成,读取另一部分?它需要一直以最大容量咀嚼,我无法一次读取整个数据库。
  • @user1713059 如果你传入一个懒加载行的IEnumerable,你不会有任何问题。如果您没有流式传输行的方法,那么您可以根据需要对它们进行批处理。
猜你喜欢
  • 1970-01-01
  • 2017-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多