c# - CRM 2011 插件中的线程/环境上下文

标签 c# multithreading dynamics-crm-2011 threadpool cross-cutting-concerns

我们最近遇到过几次这样的问题:在 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/动态拦截不是选项)这里)?

感谢您的帮助和指点。

最佳答案

简单而聪明的回答:如果你这样做会痛,那就不要那样做。 :)

您使用环境上下文模式的 self 强加要求与 CRM 的设计模式冲突。想一想 CRM 的工作原理 - 它向您传递一个 IServiceProvider,其中包含您需要的一切,包括跟踪服务。它为您处理所有复杂的多线程和优化,只要求您不要试图用花哨的模式、静态变量或线程技巧来超越它。

我的建议是使用相同的模式 - 将 IServiceProvider 传递给任何需要它的类或方法。简单得多——再加上以后当你遇到一个奇怪的错误时,你不会怀疑你是否成功地智胜了微软的工程师。 :)

关于c# - CRM 2011 插件中的线程/环境上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13886017/

相关文章:

java - 使用 PoolingClientConnectionManager 时释放连接?

javascript - odata 查询在 ie 7 中不起作用

c# - DataGridView、虚拟模式和 "lags"

c# - 从第二个组合框中删除第一个组合框的选定项目 C# Windows 窗体应用程序

c# - 改进行数据

c# - 将输入值保存在二维数组中

c++ - 引用计数类和多线程

java - 将长应用程序划分为线程

python - 如何使用 Python 连接到 Microsoft Dynamics CRM 服务器?

c#-4.0 - CRM EarlyBoundEntities 日期时间