这是我在这里发表的第一篇文章,如果结构不合理,请道歉。
我们的任务是设计一个工具:
现在所有这些个点都相对容易。我很想知道如何最好地设计一些东西来处理这个问题并快速完成它。高效地使用我们的硬件。
我们必须处理大约200万个帐户。方括号可以了解每个流程平均需要多长时间。我想使用机器上可用的最大资源--24核Xeon处理器。这不是一个内存密集型过程。
使用TPL并将每个作为任务创建是一个好主意吗?每个都必须按顺序发生,但许多可以一次完成。不幸的是,解析器没有多线程感知,我们没有源(它本质上是我们的黑盒子)。
我的想法是这样的 - 假设我们正在使用TPL:
这听起来可行还是我没有正确理解?以不同的方式分解步骤会更好吗?
我有点不确定如何处理解析器抛出异常(非常挑剔)或上传失败时的问题。
所有这些都将在一个预定的作业中作为控制台应用程序在非工作时间运行。
答案 0 :(得分:1)
我会考虑使用某种消息总线。因此,您可以分离步骤,如果一个人无法工作(例如因为REST服务暂时无法访问),您可以存储该消息以便以后处理它们。
根据您用作消息总线的内容,您可以使用它来引入线程。
在我看来,如果你有更高级别的抽象,比如服务总线,你可以更好地设计工作流程,处理异常状态等等。
另外,如果这些部件可以单独运行,它们就不会相互阻挡。
一种简单的方法是将servicestack messaging与Redis ServiceBus一起使用。
引用了一些优点:
基于消息的设计允许更容易的并行化和内省计算
可以对服务器更新后的DLQ消息进行内省,修复并稍后重播,并重新加入正常的消息工作流程
答案 1 :(得分:0)
我认为在您的案例中开始使用多个线程的简单方法是将每个帐户ID的整个操作放在线程中(或者更好,在线程池)。在下面提出的方法中,我认为您不需要控制线程间操作。
将数据放在线程池队列上的类似内容:
var accountIds = new List<int>();
foreach (var accountId in accountIds)
{
ThreadPool.QueueUserWorkItem(ProcessAccount, accountId);
}
这是您将处理每个帐户的功能:
public static void ProcessAccount(object accountId)
{
// Download the data file for this account
// ContinueWith using the data file, send to the converter
// ContinueWith check threshold, send to parser
// ContinueWith Generate Report
// ContinueWith Upload outputs
}