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 に答える