
[英]Microsoft Dynamics CRM SDK CRMServiceClient connection string cache bug
[英]Dynamics CRM CrmServiceClient - how to connect to multiple organisations?
我有一个 ASP.Net Web 应用程序,它使用 XRM 工具连接器连接到 Dynamics CRM。 我传入一个连接字符串并创建这样的连接:
CrmServiceClient conn = new CrmServiceClient(ConnectionString);
如果我连接到一个 Dynamics CRM 组织,这很有效。 但是,如果我想更改 ASP.Net 应用程序中的连接,并使用不同的连接字符串调用服务客户端
CrmServiceClient conn = new CrmServiceClient(ConnectionString**2**);
新的连接字符串将被忽略,连接仍保留为原始连接字符串。 这是由于连接池,我假设。
如果我在设置连接字符串之前调用conn.Dispose()
- 这没有区别。
有效的是在两个连接字符串中设置“ requireNewInstance=True
”。 当我这样做时,Web 应用程序能够在组织之间切换……但是 Web 应用程序的性能很糟糕。 每个页面需要 <1 秒才能加载,然后需要 30 秒或更长时间才能加载,因为每次连接都是从新创建的。
是否有两个 CrmServiceClient 实例同时处于活动状态,并连接到两个不同的 CRM 组织? 或者有什么方法可以强制处理 CrmServiceClent 并创建新的?
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)',而无需担心它是否已被实例化。 如果没有,一个新的对象将被实例化并返回。 如果它已被实例化,则将返回现有对象。
个人意见:SDK 中对CrmServiceClient
的记录非常差,不清楚开发人员打算如何使用它。 例如,处理多线程的正确方法是什么? 它实现了IDisposable
但它实际上应该包含在using
语句中吗? 以及为什么要处理它,因为目的是维护跨工作单元的连接/身份验证。 这只是令人困惑。 甚至RequireNewInstance
似乎也很古怪。
性能说明:我不确定为什么您的性能如此糟糕。 验证时间不应超过几秒钟。 这是我会研究的东西,因为它会导致生产问题,因为必须更新身份验证,并且更新可能会在页面加载期间发生 - 导致偶尔的性能下降。 例如,从我的本地机器运行设置两个CrmServiceClient
对象的时间被测量为 ~ 5-6 秒。
我在性能说明上同意 Nicknow,我们使用 V3.0.0.0 Microsoft.Xrm.Tooling.Connector 和 CRM Dynamics 360,当我们跨越多个组织时,我们没有看到任何性能问题,而不是 1,2, 3. 我们上升到 1.2.3.....14。
我在处理上也有类似的疑问。 一个建议是,最好在每次请求后删除 svcClient。 原因是因为如果令牌过期(CRM 不会提醒您),您的程序将出现一些错误异常。 重用相同是好的,但如果令牌过期则不可能。 或者您需要读取值“Token ValidFrom”和“Token ValidTo”Is Valid = True 与否。 所以你需要构建你的自定义连接池逻辑,这是很好的。 否则在请求完成后将其从缓存中删除。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.