我们最近有几次提出这样的问题:在 Dynamics CRM 2011 中,是否Execute()
保证一个插件执行(即方法的传递)保持在同一个线程上。
我想使用环境上下文模式来实现跟踪,以避免将跟踪服务传递给任何可能想要跟踪的类。问题是我们知道插件每个注册步骤只实例化一次,然后从同一个实例提供所有后续操作;这意味着我不能只拥有一些像Tracing.Current
我分配当前ITracingService
实例的静态属性,我很高兴。如果我这样做了,最后开始的操作将覆盖所有其他可能仍在运行的操作的实例(这种并发并不少见)。
现在,如果我可以确定Execute()
方法下的所有内容都保留在同一个线程中,我仍然可以使用环境上下文,利用[ThreadStatic]
静态字段的属性:
public static class Tracing
{
[ThreadStatic]
private static ITracingService _current;
public static ITracingService Current
{
get
{
if (null == _current)
{
_current = new NullTracingService();
}
return _current;
}
set { _current = value; }
}
}
我会在输入Execute()
方法时设置它并在最后清除它,以便删除对跟踪服务实例的引用。
在 MSCRM 插件的上下文中,我唯一能找到的关于线程的事情是,显然各个线程来自 ThreadPool - 无论对我的问题可能产生什么后果。
有没有人更深入地了解如何使用 MSCRM 插件处理线程 - 或者关于如何在这种特殊情况下使用 SOLID 代码优雅地处理跟踪的横切关注点的任何其他想法(AOP/动态拦截在这里没有选项)?
感谢您的任何帮助和指点。