首先,我在Microsoft Dynamics CRM插件代码中面临着奇怪的问题.
这是我的代码示例:
public class Counter : Plugin { private static object Locker = new object(); public Counter() : base(typeof(Counter)) { .... } public void GenerateNumber(LocalPluginContext localContext) { IOrganizationService service = localContext.OrganizationService; IPluginExecutionContext context = localContext.PluginExecutionContext; Entity Target = (Entity)context.InputParameters["Target"]; var Number=0; lock(Locker) { var CounterEntity = service.GetCounterEntity(); Number=(int)CounterEntity["number"]; CounterEntity["number"]=Number+1; service.Update(CounterEntity); } Target["number"]=Number; service.Update(Entity); } }
据我所知,每次创建一些实体时,系统都会创建实例Counter
并执行GenerateNumber
方法.Counter
应该从Counter Entity获取最后一个数字的实例,增加它并将其保存到数据库.但不知何故,这段代码生成了两次相同的数字.
如果计数器在不同的线程中创建,那么lock
应该完成他的工作.
为什么会这样,我怎么能解决这个问题呢?我应该用信号量替换锁吗?
每次执行插件时,平台都不会创建插件的新实例.根据SDK:
为了提高性能,Microsoft Dynamics 365会缓存插件实例.应该将插件的Execute方法编写为无状态,因为每次调用插件时都不会调用构造函数.此外,多个系统线程可以同时执行插件.所有每个调用状态信息都存储在上下文中,因此您不应使用全局变量或尝试将任何数据存储在成员变量中,以便在下一个插件调用期间使用,除非该数据是从提供给构造函数的配置参数中获取的.对插件注册的更改将导致插件重新初始化.
您尝试解决的问题经常被错误地解决.在线发布的许多解决方案都面临着同样的问题,即在同一时间创建许多记录时,会生成重复的自动编号.我理解这个问题的两个最喜欢的(也是绝对正确的)资源是:
Microsoft Dynamics CRM中的可扩展自定义设计:单击下载后,选择名为ScalableDynamicsCRMCustomizations.docx的文档.这是一份白皮书,因此很长,但它解释了你想知道的内容.特别是,请参阅标题为什么理解事务很重要的部分:自动编号示例.
如何使用Microsoft Dynamics CRM中的事务实现强大的自动编号:这要短得多,但涵盖了最重要的问题.我发现我需要完全理解白皮书才能真正理解平台的工作原理.