存在哪些C#工具用于触发、排队和确定相关任务的优先级

本文关键字:优先级 任务 排队 工具 用于 存在 | 更新日期: 2023-09-27 18:22:40

我有一个C#服务应用程序,它与数据库交互。它最近从.NET 2.0迁移到了.NET 4.0,所以我们可以使用很多新工具。

我正在寻找编程方法或工具/库的指针,以处理定义任务、配置它们所依赖的任务、排队、排序、取消等。

有各种类型的服务:

  • 数据(用于检索和更新)
  • 计算(用数据计算结果填充某些表格)
  • 报告

这些服务通常相互依赖,并按需触发,即报告任务中可能包含等代码

if (IsSomeDependentCalculationRequired())
    PerformDependentCalculation();  // which may trigger further calculations
GenerateRequestedReport();

此外,任何数据修改都可能在某些计算报告服务上设置Required标志,(因此报告在生成完成之前可能已过期)。任务的长度从几秒钟到几分钟不等,并且在事务中执行。

到目前为止,这还可以,但扩展性不好。有一些基本的设计问题,我希望重写这部分代码。例如,如果两个用户在相似的时间请求相同的报告,则相关任务将执行两次。此外,目前无法取消正在进行的任务。很难维护依赖的任务等。

我不是在寻找如何实现修复的建议。相反,如果我从零开始使用.NET4,我会寻找用于此类需求的工具/库的指针。这是否适合Windows工作流?这就是期货的作用吗?有没有其他图书馆我应该看看,或者我应该读的书或博客文章?

编辑:Rx反应扩展怎么办?

存在哪些C#工具用于触发、排队和确定相关任务的优先级

我认为您的需求不适合任何内置的东西。你的要求太具体了。

我建议您围绕SQL数据库构建一个任务队列基础结构。您的任务非常长时间运行(秒),因此您不需要在任务调度程序中有特别高的吞吐量。这意味着您不会遇到性能障碍。从编程的角度来看,这实际上是一项非常容易管理的任务。

您可能应该构建一个windows服务或其他进程,以便不断轮询数据库中的新任务或请求。然后,该服务可以对请求的任务强制执行任意规则。例如,它可以检测到报告任务已经在运行,而不安排新的计算。

我的主要观点是,您的需求非常具体,需要使用C#代码对它们进行编码。您无法使现有工具满足您的需求。你需要编程语言的图灵完整性来自己完成这项工作。

编辑:您可能应该将任务请求与任务执行分离。这允许多方请求刷新某些报告,同时只有一个实际计算在运行。一旦完成了该单个计算,所有任务请求都被标记为已完成。当请求被取消时,不需要取消执行。只有当最后一个请求被取消时,任务执行也会被取消。

编辑2:我不认为工作流是解决方案。工作流通常彼此独立运行。但你不想那样。您希望有跨多个任务/工作流的规则。您将使用基于工作流的模型来对抗系统。

编辑3:关于TPL(任务并行库)的几句话。你提到了它("期货")。如果您想了解任务如何协同工作、如何创建依赖关系以及如何组合任务,请查看任务并行库(特别是Task和TaskFactory类)。你会在那里找到一些不错的设计图案,因为它设计得很好。以下是对任务序列进行建模的方法:调用Task.ContinueWith,它将继续函数注册为新任务。以下是对依赖关系进行建模的方法:TaskFactory.WhenAll(Task[])启动一个任务,该任务仅在其所有输入任务完成时运行。

但是:TPL本身可能不太适合你,因为它的任务无法保存到磁盘上。当您重新启动服务器或部署新代码时,所有现有任务都将被取消,进程将中止。这可能是不可接受的。请用TPL作为灵感。从中了解什么是"任务/未来",以及如何构成它们。然后实施你自己的任务形式。

这有帮助吗?

我会尝试使用无状态状态机包来建模工作流。使用包将提供一种一致的方式来跨各种服务提升工作流的状态。您的每个服务都将拥有一个内部状态机实现,并公开推进它的方法。无状态将负责根据工作流的状态触发操作,并强制您显式设置它可以处于的各种状态-这对维护特别有用,可能有助于您更好地了解域。

如果您想以可扩展的方式正确解决这个基本问题,您可能应该采用SOA架构风格。您的服务将接收命令并生成您可以处理的事件,以便对系统中发生的事实作出反应。

是的,有一些工具可以实现。例如,NServiceBus是构建SOA系统的绝佳工具。

您可以使用SQL数据代理在定时间隔内运行SQL查询。你必须自己编写应用程序,它看起来像。写得像一个长时间运行的程序,它检查时间并做一些事情。我不认为有clearcut工具可以做你想做的事情。做C#应用程序,WCF服务。数据自动化可以在sql本身中完成。

如果我理解得对,你想缓存生成的报告,然后不再工作。正如其他评论者所指出的,这可以通过多个生产者/消费者队列和一些缓存来优雅地解决。首先,您将报告请求排入队列。根据报告生成参数,如果以前生成的报告已经可用,您可以首先检查缓存,然后简单地返回此报告。如果由于数据库中的更改,报告变得过时,则需要注意以可靠的方式使缓存无效。

现在,如果尚未生成报告,则需要安排生成报告。报告调度程序需要检查是否已经生成了相同的报告。如果是,则注册一个事件以在完成时通知您,并在完成后返回报告。请确保您没有通过缓存层访问数据,因为它可能会产生竞争(生成报告,更改数据,完成的报告将立即被缓存丢弃,并留下要返回的注释)。

或者,如果你确实想防止返回过时的报告,你可以让缓存层成为你的主要数据提供商,它将生成尽可能多的报告,直到及时生成一个没有过时的报告。但请注意,如果数据库中有持续的更改,如果报告生成时间与数据库更改之间的平均时间一样长,那么您可能会不断生成无效报告,从而进入一个无休止的循环。

正如您所看到的,您在这里有很多选择,而不必真正讨论.NET、TPL、SQL server。首先,你需要设定你的目标,你的系统应该有多快/可扩展和可靠,然后你需要为你的特定问题领域选择合适的架构设计,如上所述。我不能为你做这件事,因为我没有你的全部领域,知道什么是可以接受的,什么是不可以接受的。

棘手的部分是不同队列之间的切换部分,并提供适当的可靠性和正确性保证。根据您的特定报告生成需求,您可以将此逻辑放入云中,也可以使用单个线程,将所有工作放入适当的队列中,并同时或逐个或介于两者之间进行处理。

TPL和SQL server当然可以提供帮助,但它们只是工具。如果由于对其中一个或另一个没有足够的经验而使用错误,可能会发现不同的方法(如仅在内存中使用队列和在文件系统中使用持久化报告)更适合您的问题。

根据我目前的理解,我不会使用SQL服务器将其滥用为缓存,但如果你想要一个数据库,我会使用RavenDB或RaportDB之类的东西,与全面的SQL服务器相比,它们看起来稳定且重量轻得多。

但是,如果您已经有一个SQL服务器在运行,那么继续使用它。

我不确定我是否正确理解您的意思,但您可能想看看JAMS Scheduler:http://www.jamsscheduler.com/.它不是免费的,但它是一个非常好的系统,可以根据任务和报告进行调度。我在上一家公司成功地使用了它。它是用.NET编写的,并且有一个.NET API,所以你可以编写自己的应用程序与JAMS通信。他们也得到了很好的支持,并渴望实现新的功能。