【发布时间】:2012-12-02 21:18:15
【问题描述】:
我们最近遇到过几次这样的问题:在 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/动态拦截不是选项在这里)?
感谢您的帮助和指点。
【问题讨论】:
-
我理解您对以线程安全方式运行的担忧,但我不确定我是否理解您为什么担心在同一个线程上运行。你能再解释一下吗?
-
好吧,我需要避免插件执行被移动到另一个线程,而没有再次“附加”它自己的 ITracingService 实例。我还没有弄清楚在这种情况下如何处理 ThreadStatic。
标签: c# multithreading dynamics-crm-2011 threadpool cross-cutting-concerns