2

我想证明在线程之间重用 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;
    }
}

SDK 声明OrganizationServiceProxy 的任何实例成员都不能保证是线程安全的。

如何导致线程之间共享的 OrganizationServiceProxy 出现问题?

会出现什么样的问题?

4

1 回答 1

2

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

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

于 2015-05-10T23:30:28.743 回答