CrmServiceClient 不处理缓存多个连接字符串的连接。您需要自己处理缓存部分。除非你有一个不受限制的列表,否则这通常可以通过两个对象来处理。
var org1SvcClient = new CrmServiceClient(org1ConnString);
var org2SvcClient = new CrmServiceClient(org2ConnString);
只要您将RequireNewInstance=true 作为每个连接字符串的一部分,您就会有两个不同的对象指向两个不同的组织。
如果您有很多连接字符串,您可能希望使用字典来缓存它们,这样您就可以通过连接字符串文本简单地引用它们来获取正确的对象。
这是一个这样的缓存类应该是什么样子的快速示例:
public static class CrmServiceClientCache
{
private static Dictionary<string, CrmServiceClient> _internalCache = new Dictionary<string, CrmServiceClient>();
private static Object _objLock = new object();
public static CrmServiceClient Get(string connectionString)
{
if (_internalCache.ContainsKey(connectionString)) return _internalCache[connectionString];
else
{
lock (_objLock)
{
if (!_internalCache.ContainsKey(connectionString) && _internalCache[connectionString] != null)
{
var svcClient = new CrmServiceClient(connectionString);
if (svcClient.IsReady) _internalCache[connectionString] = svcClient;
else throw new Exception($"Failed to Successfully Create CrmServiceClient: {svcClient.LastCrmError}", svcClient.LastCrmException);
}
return _internalCache[connectionString];
}
}
}
}
然后在您的代码中,只要您想要一个特定连接字符串的 CrmServiceClient 实例,您就可以执行以下操作:
现在您可以从代码中的任何位置调用“CrmServiceClientCache.Get(org1ConnString)”,而不必担心它是否已被实例化。如果没有,则将实例化并返回一个新对象。如果已实例化,则返回现有对象。
个人意见:CrmServiceClient 在 SDK 中的记录很差,不清楚它打算如何被开发人员使用。例如,处理多线程的正确方法是什么?它实现了IDisposable,但它实际上应该包含在using 语句中吗?以及为什么要处理它,因为目的是保持跨工作单元的连接/身份验证。这只是令人困惑。甚至RequireNewInstance 看起来也很古怪。
性能说明:我不确定您为什么会得到如此糟糕的性能。进行身份验证的时间不应超过几秒钟。这是我会研究的东西,因为它会导致生产问题,因为必须更新身份验证并且更新可能会在页面加载期间发生 - 导致偶尔的性能下降。例如,从我的本地计算机运行设置两个 CrmServiceClient 对象的时间约为 5-6 秒。