8

检查我的 Tridion 内容管理服务器上的事件日志时,(我使用的是 2009 版本)我看到警告说:

Session is used on another thread... than it was created on ... 
Session objects are not thread safe.

哪些编程/模板实践可能会导致这种情况?

编辑:到目前为止,我们有一些很好的建议:

  1. 不要将会话对象存储在静态变量中 (Chris)
  2. 不要将引擎或包存储在静态变量中 (Miguel)

事实上,这两者都是纯金,你应该检查你自己的代码是否有这些反模式。(引擎有一个会话的引用,所以这是有道理的。)不过,我已经搜索了导致问题的代码库,但我没有找到任何这些。那么 - 有没有人有更多的想法?我也欢迎有关如何调试此类事情或缩小有问题的代码范围的建议。

4

4 回答 4

9

该问题不仅出现在存储会话时,而且出现在存储任何 TOM.NET 对象(ComponentPage等)时。每个这样的对象都有一个对 Session 的内部引用,它是从对对象的任何访问中创建的,可能必须返回到 Session 以从 Tridion 检索请求的信息。

尽管大多数对项目类型“本机”的属性似乎都被检索并保存在实例上,但类似的调用LoadApplicationData可能(必须)返回到 Session 以访问请求的数据。如果此调用随后发生在不同的线程上,您将收到您提到的警告消息。

我已经开始查看我怀疑的每个 TOM.NET 对象,并在我第一次从其 Session 加载对象时预加载我以后可能需要的大量数据。

于 2012-05-07T21:08:33.963 回答
8

我还想根据以前的经验添加评论。以下场景:

  • 会话和/或引擎和/或包存储在静态变量中
  • 会话和/或引擎和/或包作为参数发送到静态方法

除了前面描述的问题外,还可能导致几个问题,包括发布期间的内存泄漏。

Publisher 将开始消耗内存,直到最终处于无响应模式(您不能停止,也不能重新启动或禁用)并且您需要重新启动服务器。

在进行大规模出版时,这些问题可能会变得更糟

所以建议任何使用会话、引擎、包的东西都应该转换为非静态的

例如,从以下用于初始化跨所有模板使用的实用程序的代码开始

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using Tridion;
using Tridion.ContentManager;
using Tridion.ContentManager.CommunicationManagement;
using Tridion.ContentManager.ContentManagement;
using Tridion.ContentManager.ContentManagement.Fields;
using Tridion.ContentManager.Templating;
using Tridion.ContentManager.Publishing;


namespace sample.sample1
{
    public class Utilities
    {
        private static Engine  _engine;
        private static Package _package;

        public void InitializeUtilities(Engine e, Package p)
        {
            _engine = e;
            _package = p;
        }
    }
}

进入

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using Tridion;
using Tridion.ContentManager;
using Tridion.ContentManager.CommunicationManagement;
using Tridion.ContentManager.ContentManagement;
using Tridion.ContentManager.ContentManagement.Fields;
using Tridion.ContentManager.Templating;
using Tridion.ContentManager.Publishing;


namespace sample.sample1
{
    public class Utilities
    {
        private Engine _engine;
        private Package _package;

        public void InitializeUtilities(Engine e, Package p)
        {
            _engine = e;
            _package = p;
        }
    }
}

可以省去很多问题

于 2012-04-19T18:27:11.057 回答
6

I have found that if you ever store the session object in a static variable in a template this error occurs. It works fine in debug mode, but as soon as I run a multi-threaded Publisher (i.e. more than one rendering thread) this issue raises it's ugly head.

于 2012-04-18T16:46:18.330 回答
0

另一种情况是,如果您的事件系统或模板或工作流代码启动子线程并将会话或引擎对象传递给它们而没有适当的锁定。

基本上任何不属于单线程公寓模型的东西,引擎和会话对象都基于: http: //msdn.microsoft.com/en-us/library/windows/desktop/ms680112(v=vs.85) .aspx

于 2012-10-18T03:21:47.317 回答