证明OrganizationServiceProxy不是线程安全的

时间:2015-05-10 19:20:54

标签: thread-safety dynamics-crm-2011 dynamics-crm dynamics-crm-2013 dynamics-crm-2015

我想证明在线程之间重用OrganizationServiceProxy实例会导致问题。

此控制台应用程序在线程之间重复使用相同的OrganizationServiceProxy实例时没有问题:

class Program
{
    private static OrganizationServiceProxy Service { get; set; }

    static void Main(string[] args)
    {
        Connect(); // Initializes Service

        for (int i = 0; i < 100; i++)
        {
            int index = i;
            Task.Run(() =>
                {
                    for (int i2 = 0; i2 < 10; i2++)
                    {
                        try
                        {
                            Console.WriteLine("Creating" + index);
                            Entity record = new Entity("account");
                            record.Id = new Guid("4986e130-45f7-e411-9454-00155d91de01");
                            record["name"] = index + " - " + i2;
                            Service.Update(record);
                            Console.WriteLine("Created" + index);
                        }
                        catch (Exception e)
                        { }
                    }
                });
        }
        Console.ReadLine(); // the name of the record ends up as 99 - 9, which is right
    }

    /* Initialize Service */
    private static bool Connect()
    {
        try
        {
            ClientCredentials cred = new ClientCredentials();
            cred.UserName.UserName = @"r";
            cred.UserName.Password = @"";
            IServiceManagement<IOrganizationService> serviceManagement = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(@"/XRMServices/2011/Organization.svc"));
            Service = new OrganizationServiceProxy(serviceManagement, cred);
            var who = new Microsoft.Crm.Sdk.Messages.WhoAmIRequest(); // used to test the connection
            var whoResponse = (Microsoft.Crm.Sdk.Messages.WhoAmIResponse)Service.Execute(who); // this fails if not connected       
        }
        catch (Exception e)
        {
            Console.WriteLine("Connecting to CRM.\n" + e.Message + ((e.InnerException != null) ? "\n" + e.InnerException.Message : ""));
            return false;
        }
        return true;
    }
}

The SDK states无法保证OrganizationServiceProxy的任何实例成员都是线程安全的。

如何在线程之间共享OrganizationServiceProxy时出现问题?

预计会出现什么问题?

1 个答案:

答案 0 :(得分:2)

我不确定我是否知道您问题的具体答案,但标记为不保证线程安全的内容只是意味着:它可能是安全的,但作者尚未对其进行测试或具体为这些类编写任何线程安全的代码,因此无法保证线程安全。

我知道线程安全肯定会与服务器上的插件一起发挥作用。这就是为什么你不应该在Plugin类中使用本地字段的原因。 Plugin引擎重新使用Plugin类的实例,而不是为每次执行重新实例化它们。这意味着您的插件可能会在最后一个线程使用的那些本地字段中使用“旧数据”执行,这显然会导致各种问题。