我有两个Sitecore代理程序作为计划作业运行。代理A是一个长期运行的任务,具有低优先级。代理B是一个短期运行的任务,具有高优先级。 B以比A的间隔短的间隔运行。
问题是当A已经在运行时,B永远不会运行。
我已经实现了this,以便能够在内容编辑器中手动运行代理。当我这样做时,我能够运行B,虽然A已经在运行(即使我在自定义对话框中将它们设置为相同的线程优先级)。
如何在配置文件中指定B的优先级高于A?或者使我的预定作业设置为多线程,以便在Sitecore中同时运行作业?有没有标准的方法来做到这一点?
我尝试了like this,我在代理实现中设置了线程优先级,但是当A已经运行时,从不在B中调用此代码。所以优先排序应该以某种方式完成"之前"工作实施本身。
答案 0 :(得分:4)
正如在另一个答案中已经提到的,Sitecore计划任务是按顺序运行的,因此每个代理仅在前一个代理完成后运行。
但是,数据库中定义的任务可以运行async
,这意味着您可以安排多个任务以并行方式运行。
您需要创建一个Command并定义一个Schedule:
定义命令
命令在Sitecore客户端中定义。
定义时间表
数据库代理将根据计划中的设置执行命令。
Async
。您可以详细了解Database Scheduler in the Sitecore Community Docs。
请注意,如果您安排太多任务并行运行,这可能会导致性能问题。
如果您无法为config中定义的任务传递参数,则从数据库运行计划任务的缺点。如果您不能简单地从代码访问配置设置(并且需要传入),那么对于在配置中定义的计划任务,您可以从计划任务代码中调用Sitecore作业。 Sitecore Jobs作为一个线程运行,每个作业都会启动一个新线程,因此可以并行运行,只需确保作业名称是唯一的(同名作业将排队)。
答案 1 :(得分:1)
原因是因为Sitecore计划作业按顺序运行。因此,如果您正在执行某项工作,则在完成之前不会触发其他工作。
如果我没有弄错的话,sitecore会将当前正在运行的作业后需要执行的其他作业排队。
由于您使用运行代理工具触发作业,因此您将强制执行该代理。除了发布之外,它不会检查是否有其他作业正在运行,它将排队,因为它正在将项目从Source转移到Target数据库。
修改强>
您可以从Sitecore v8.x的 Web.config 或针对Sitecore v8.x的 Sitecore.config 查看<job>
。您将看到用于作业的管道。如果我没有弄错,我认为您需要检查调度程序的代码。命名空间为Sitecore.Tasks.Scheduler, Sitecore.Kernel
由于
答案 2 :(得分:1)
正如您可能已经从Hishaam的回答中了解到的那样(不会重复这些好的信息),使用Sitecore代理可能不是您尝试做的最佳解决方案。对于类似的设置(需要在电子商务站点上执行导入,导出或其他排队任务的任务),我使用了外部调度引擎(在我的案例中,Hangfire可以很好地完成工作,但你也可以使用其他工具)在我的Sitecore解决方案中调用服务。作为到达Sitecore的图层执行的服务。
您可以决定使用这些服务的程度(甚至可以启动新线程),但它们可以彼此相邻运行。这样您就不会遇到另一个进程仍在运行的问题。我选择了一个架构,在这个架构中,服务非常薄,面向真正的业务逻辑。
您可能需要确保在运行时无法调用一个服务背后的代码(我需要在处理队列时执行此操作),但这些内容都可以在.net代码中完成。
我发现这种设置更加强大,特别是对于重要的任务。在需要运行任务时,它也更容易配置。
答案 3 :(得分:0)
在意识到运行我的高优先级计划任务B作为Sitecore中的后台代理不是一个好的解决方案后,我最终得到了以下解决方案。为了这个答案,我现在打电话给B:ExampleJob
我创建了一个名为ExampleJobStarter
的新代理类。这项工作的目的只是启动另一个运行实际工作的线程ExampleJob
:
public class ExampleJobStarter
{
public override void Run()
{
if (ExampleJob.RunTheExampleJob) return;
ExampleJob.RunTheExampleJob = true;
Task.Run(() => new ExampleJob().Run());
}
}
public class ExampleJob
{
public static bool RunTheExampleJob;
public override void Run()
{
while (RunTheExampleJob)
{
DoWork();
Thread.Sleep(10000);
}
}
private void DoWork()
{
... // here I perform the actual work
}
}
ExampleJobStarter
现已在我的Sitecore配置文件中注册,每10分钟运行一次。我还从Sitecore配置中删除了ExampleJob
,因此它不会自动运行(因此,它本身不再是Sitecore作业)。 ExampleJobStarter
只会确保ExampleJob
正在另一个线程中运行。 ExampleJob
本身将每10秒完成一次工作,而不会被仍然作为普通后台代理运行的低优先级作业代理干扰。
如果沿着这条路走下去,请注意死锁问题(对于我在这种情况下使用的数据不是问题)。