Tea*_*Dev 6 c# multithreading cross-cutting-concerns threadpool dynamics-crm-2011
我们最近有几个问题出现在Dynamics CRM 2011中,一个插件执行(即Execute()方法的传递)保证保持在同一个线程上.
我想使用Ambient Context模式实现跟踪,以避免将跟踪服务传递给任何可能要跟踪的类.问题在于,正如我们所知,插件仅在每个注册步骤中实例化一次,然后从同一实例提供所有后续操作; 这意味着我不能只有一些静态属性,比如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; }
}
}
Run Code Online (Sandbox Code Playgroud)
我会在输入Execute()方法时设置它并在最后清除它,以便删除对跟踪服务实例的引用.
我唯一可以在MSCRM插件的上下文中找到线程的方法是,显然单个线程来自ThreadPool - 无论对我的问题可能产生什么后果.
有没有人更深入地了解如何使用MSCRM插件处理线程 - 或者在这种特殊情况下如何使用SOLID代码优雅地处理跟踪问题的任何其他想法(AOP /动态拦截在这里没有选项)?
感谢您的帮助和指点.
简单而聪明的答案是:如果这样做会让你感到疼痛,那就不要这样做。:)
您对使用环境上下文模式的自我要求与 CRM 的设计模式相冲突。想一想 CRM 的工作原理 - 它会向您传递一个IServiceProvider,其中包含您需要的一切,包括跟踪服务。它为您处理所有复杂的多线程和优化,并且只要求您不要尝试用花哨的模式、静态变量或线程技巧来智胜它。
我的建议是使用相同的模式 - 将 传递IServiceProvider给任何需要它的类或方法。更简单 - 再加上以后当你遇到一个奇怪的错误时,你就不会怀疑你是否成功地智胜了微软的工程师。:)
| 归档时间: |
|
| 查看次数: |
2073 次 |
| 最近记录: |