Orchard CMS:在循环中创建ContentItem会产生延迟

时间:2015-03-11 10:30:58

标签: c# orchardcms orchardcms-1.8

根本问题
我面临的问题源于需要从电子表格导入数据。 导入开始后,用户必须能够离开页面并在导入完成后稍后返回 到目前为止,我所知道的选项是Orchard的计划任务和后台工作人员,根据我的理解,他们每次都会被扫描一次触发。 (如果有一个我忽略的更好的选择,请告诉我)

问题
我基本上必须在循环中创建新的内容项。在遇到一些问题一段时间之后,我已经设置了一个非常简单的测试,其中ajax调用为每个调用创建X个虚拟项目并对其进行计时。
我发现每次迭代创建项目所需的时间会略有增加。如果第一个项目可能需要20 ms来创建,则循环中的nr 200将需要150 ms来创建。而且似乎没有这个问题,每次迭代都会变得越来越糟。

如果您想查看测试代码:

    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 ms开始。它在第一次和第二次ajax调用之间的微小间隔内没有完全恢复,但确实产生了巨大的差异。

我认为这可能与离开WorkContext有关吗? 但是当我留在循环中时,我找不到强制这种情况发生的方法。 由于扫描每分钟只运行一次,我无法想到避免这种循环的方法。

问题
有什么我可以做的,以避免在循环内部的这种延迟累积,或者可能是另一种运行我忽略的导入的方法? (请记住,当用户不在页面上时,必须在后台运行) (值得一提的是我上次测试的项目没有来自Lucene的搜索索引,但它确实有我认为需要添加到字段索引的字段。如果这有所不同)

谢谢。

1 个答案:

答案 0 :(得分:2)

我们在数据导入过程中遇到了类似的问题,即创建了大量内容项

我们采取的步骤是:

  • 将导入移至Orchard Command
    • 这意味着您不在IIS工作进程以及与在那里运行创建代码相关的任何超时/锁定
    • 如果您需要将流程保留在Orchard UI中,这可能不是您的选择。
  • 将工作移至批次,而不是在每个项目之后,或循环调用中的每个x项目
    • _orchardServices.TransactionManager.RequireNew()强制提交交易
    • _orchardServices.ContentManager.Clear()清除对任何内容项的引用

您需要注入IOrchardServices才能访问这些方法。