Sitecore项反序列化很慢/触发缓存清除

时间:2015-09-28 18:09:43

标签: sitecore sitecore8

问题:当使用Sitecore.Data.Serialization.Manager将序列化项反序列化到Sitecore 8时,我的缓存会被清除。这不应该是这样,因为我用这样的选项DisableEvents = true来称呼它:

var options = new Sitecore.Data.Serialization.LoadOptions(masterDb);
options.ForceUpdate = true;
options.DisableEvents = true;

using (new Sitecore.SecurityModel.SecurityDisabler())
{
    Sitecore.Data.Serialization.Manager.LoadItem(itemPath, options);
}

尽管如此,缓存正在被清除 - 启用调试后,我明白了:

  

36956 19:32:31 INFO从路径加载项目   /master/sitecore/templates/SomeFolder/SomeItem.item。

     

36956 19:32:34警告全部   缓存已被清除。这会大大降低性能。

     

36956 19:32:34 DEBUG所有缓存都已清除。堆栈跟踪:      在   System.Environment.GetStackTrace(Exception e,Boolean needFileInfo)
  在System.Environment.get_StackTrace()处   Sitecore.Caching.CacheManager.ClearAllCaches()at   Sitecore.Data.Serialization.Manager< .cctor> b__1(SerializationFinishedEvent   事件)在Sitecore.Eventing.EventProvider.RaiseEvent(对象事件,   输入eventType,EventContext context)   Sitecore.Data.Serialization.Manager.DeserializationFinished(字符串   的databaseName)

2 个答案:

答案 0 :(得分:2)

Frederik,在您的回答中,您粘贴了LoadItem方法的反汇编代码,并在行中添加了注释,您认为存在错误:

// QUOTE FROM THE AUTHOR OF THE QUESTION, Frederik Struck-Schøning
public static Item LoadItem(string path, LoadOptions options)
{
    Assert.ArgumentNotNullOrEmpty(path, "path");
    Assert.ArgumentNotNull((object) options, "options");
    if (!options.DisableEvents) <-------------------------- HERE IS THE BUG
      return Manager.DoLoadItem(path, options);
    Item obj;
    using (new EventDisabler())
        obj = Manager.DoLoadItem(path, options);
    //This next line fires the events - but to get here, DisableEvents must be true.
    Manager.DeserializationFinished(Manager.GetTargetDatabase(path, options));
    return obj;
}

然后你解释了为什么你认为这段代码不正确。

实际上,与你所写的内容完全相反

当您将DisableEvents设置为 false 的项目反序列化时,所有缓存都会由item:saved和其他事件自动更新。

如果您告诉Sitecore禁用所有事件,则永远不会刷新缓存。这就是为什么Sitecore在反序列化后执行ClearAllCaches的原因。不幸的是,在堆栈跟踪中,您会看到名称“event”。所有Sitecore活动(如item:addeditem:createditem:saved等均未执行。只执行一个事件来通知当前实例和远程Sitecore实例,此事件为SerializationFinishedEvent(在本地和远程版本中)。

所以这是 Sitecore 错误,而是命名问题。这可能会产生误导,但一切都按预期工作。每次保存,更新,重命名等项目时,都不会执行一系列事件,而是在DoLoadItem方法完成后只有一个通知。

答案 1 :(得分:0)

修改/更新

马立克的回答让我意识到,我说错了。我会保留原来提出的答案,以免引起混淆。但总而言之,使用选项LoadItem调用DisableEvents方法可以正常工作。只有它 - 为了弥补缺乏适当的事件被触发 - 触发Manager.DeserializationFinished(...)反过来(至少根据我的默认Sitecore 8设置)调用CacheManager.ClearAllCaches()

我的错误结论是由使用Sitecore自己的* EventProvider *调用CacheManager.ClearAllCaches()方法的事实引发的 - 因此,正如Marek指出的那样 - 这是一个令人遗憾的巧合/命名冲突。

实际上,触发CacheManager.ClearAllCaches()是我想要避免的。所以我猜这个&#34;解决方法&#34;使我的反序列化更快(因为它没有清除每次执行的所有缓存)。

原始帖子

好的,所以我去了小镇并最终发现了这个,反汇编Sitecore.Data.Serialization.Manager.LoadItem(...)方法(注意:这是Sitecore 核心内容(带有我的评论)):

public static Item LoadItem(string path, LoadOptions options)
    {
      Assert.ArgumentNotNullOrEmpty(path, "path");
      Assert.ArgumentNotNull((object) options, "options");
      if (!options.DisableEvents) <-------------------------- HERE IS THE BUG
        return Manager.DoLoadItem(path, options);
      Item obj;
      using (new EventDisabler())
        obj = Manager.DoLoadItem(path, options);
      //This next line fires the events - but to get here, DisableEvents must be true.
      Manager.DeserializationFinished(Manager.GetTargetDatabase(path, options));
      return obj;
    }

这看起来像个错误。 &#34;如果不是options.DisableEvents返回&#34;。有太多的&#34;不是&#34;?

解决方法只是设置

options.DisableEvents = false;

将其设置为false会禁用在SerializationFinishedEvent监听的事件,在这种情况下是一个处理程序,它会触发堆栈跟踪提示的Sitecore.Caching.CacheManager.ClearAllCaches()。即使看起来它应该是另一种方式。