Orchard CMS:在循环中创建 ContentItems 会增加延迟
Orchard CMS: Creating ContentItems in a loop builds up a delay
根本问题
我面临的问题源于需要从电子表格导入数据。
导入开始后,用户必须能够离开页面,并且 return 稍后在导入完成时离开。
到目前为止,我所知道的选项是 Orchard 中的计划任务和后台工作人员,据我所知,他们都是每分钟被扫描触发一次。 (如果有我忽略的更好的选择,请告诉我)
问题
我基本上必须循环创建新的内容项。在遇到一些问题一段时间后,我设置了一个非常简单的测试,使用 ajax 调用为每个调用创建 X 个虚拟项目并对其计时。
我发现每次迭代创建项目所需的时间都会略有增加。创建第一个项目可能需要 20 毫秒,而循环中的 nr 200 将需要 150 毫秒来创建。而且这似乎没有上限,每次迭代都会变得更糟。
如果您想查看测试代码:
public TimeSpan CreateRandomItem(int nr)
{
Stopwatch sw = Stopwatch.StartNew();
ContentItem item = _services.ContentManager.New("MyItemType");
var myPart = item.As<MyPart>();
myPart.Name = "Test nr " + nr;
_services.ContentManager.Create(item);
sw.Stop();
return sw.Elapsed;
}
public JsonResult TestCreation(int amount, int nrReached)
{
StringBuilder sb = new StringBuilder();
for (int i = nrReached + 1; i <= (nrReached + amount); i++)
{
TimeSpan elapsed = _associationImportService.CreateRandomAssociation(i);
sb.Append("\n - Nr " + i + " took " + elapsed.TotalMilliseconds + "ms");
}
return Json(sb.ToString(), JsonRequestBehavior.AllowGet);
}
循环完成后,ajax 调用再次触发,现在延迟大大减少,从大约 30 毫秒开始。它并没有在第一次和第二次 ajax 调用之间的微小间隔内完全恢复,但确实产生了巨大的差异。
我假设这可能与离开 WorkContext 有关?
但是当我留在循环中时,我找不到一种方法来强制发生这种情况。
由于每分钟扫描一次 运行s,我想不出避免这种循环的方法。
问题
有什么我可以做的来避免在循环内产生这种延迟累积,或者可能是另一种 运行ning 我忽略的导入方法吗?
(请记住,当用户不在页面上时,这必须在后台 运行)
(可能值得一提的是我上次测试的项目没有来自 Lucene 的搜索索引,但它确实有我认为需要添加到字段索引中的字段。如果这有所不同)
谢谢。
我们在数据导入期间创建大量内容项时遇到了类似的问题
我们采取的步骤是:
- 将导入移动到 Orchard Command
- 这意味着您不在 IIS 工作进程以及与 运行 您的创建代码相关的任何超时/锁定之外
- 如果您需要将流程保留在 Orchard 中,这可能不适合您 UI。
- 改为将工作移至批次,并在每个项目之后,或循环调用中的每个 x 项目之后
_orchardServices.TransactionManager.RequireNew()
强制提交事务
_orchardServices.ContentManager.Clear()
清除对任何内容项的引用
您需要注入 IOrchardServices
才能访问这些方法。
根本问题
我面临的问题源于需要从电子表格导入数据。
导入开始后,用户必须能够离开页面,并且 return 稍后在导入完成时离开。
到目前为止,我所知道的选项是 Orchard 中的计划任务和后台工作人员,据我所知,他们都是每分钟被扫描触发一次。 (如果有我忽略的更好的选择,请告诉我)
问题
我基本上必须循环创建新的内容项。在遇到一些问题一段时间后,我设置了一个非常简单的测试,使用 ajax 调用为每个调用创建 X 个虚拟项目并对其计时。
我发现每次迭代创建项目所需的时间都会略有增加。创建第一个项目可能需要 20 毫秒,而循环中的 nr 200 将需要 150 毫秒来创建。而且这似乎没有上限,每次迭代都会变得更糟。
如果您想查看测试代码:
public TimeSpan CreateRandomItem(int nr)
{
Stopwatch sw = Stopwatch.StartNew();
ContentItem item = _services.ContentManager.New("MyItemType");
var myPart = item.As<MyPart>();
myPart.Name = "Test nr " + nr;
_services.ContentManager.Create(item);
sw.Stop();
return sw.Elapsed;
}
public JsonResult TestCreation(int amount, int nrReached)
{
StringBuilder sb = new StringBuilder();
for (int i = nrReached + 1; i <= (nrReached + amount); i++)
{
TimeSpan elapsed = _associationImportService.CreateRandomAssociation(i);
sb.Append("\n - Nr " + i + " took " + elapsed.TotalMilliseconds + "ms");
}
return Json(sb.ToString(), JsonRequestBehavior.AllowGet);
}
循环完成后,ajax 调用再次触发,现在延迟大大减少,从大约 30 毫秒开始。它并没有在第一次和第二次 ajax 调用之间的微小间隔内完全恢复,但确实产生了巨大的差异。
我假设这可能与离开 WorkContext 有关? 但是当我留在循环中时,我找不到一种方法来强制发生这种情况。 由于每分钟扫描一次 运行s,我想不出避免这种循环的方法。
问题
有什么我可以做的来避免在循环内产生这种延迟累积,或者可能是另一种 运行ning 我忽略的导入方法吗?
(请记住,当用户不在页面上时,这必须在后台 运行)
(可能值得一提的是我上次测试的项目没有来自 Lucene 的搜索索引,但它确实有我认为需要添加到字段索引中的字段。如果这有所不同)
谢谢。
我们在数据导入期间创建大量内容项时遇到了类似的问题
我们采取的步骤是:
- 将导入移动到 Orchard Command
- 这意味着您不在 IIS 工作进程以及与 运行 您的创建代码相关的任何超时/锁定之外
- 如果您需要将流程保留在 Orchard 中,这可能不适合您 UI。
- 改为将工作移至批次,并在每个项目之后,或循环调用中的每个 x 项目之后
_orchardServices.TransactionManager.RequireNew()
强制提交事务_orchardServices.ContentManager.Clear()
清除对任何内容项的引用
您需要注入 IOrchardServices
才能访问这些方法。