I am simply incrementing a static global variable in a Dynamics CRM 2016 plugin and it shows strange random pattern as shown below. Why does it show strange behavior and pattern?
Below is the code I am using.
public class MyPlugin : IPlugin
{
private static int count = 0;
public void Execute(IServiceProvider serviceProvider)
{
try
{
if (_objContext.InputParameters.Contains("Target") && _objContext.InputParameters["Target"] is Entity)
{
WriteLog("Count value before increament: " + count, service);
count = count + 1;
WriteLog("Count value after increament: "+count, service);
}
}
}
}
From the looks of it, you have two Application webservers that are currently hosting your CRM instance (or these are async plugins, in which case, you have two async servers servicing your CRM instance) Each server has it's own local version of MyPlugin.count
, which is why you're seeing the strange behavior.
App Domains in CRM are a little bit simpler for unsandboxed plugins, it's one per Crm Web Server. Sandboxed plugins are a bit trickier. Each registration step of the plugin, has its own unique domain. This requires the CRM Database (or something else external to CRM) in order to keep these values in sync.
I have created an auto-numbering solution that does do just that using the Version feature new in CRM 2015 that allows for optimistic updates. But unfortunetly, Microsoft has a bug where the Version # is null for sandboxed plugins, so it will only work in an on-prem environment, until the bug is resolved.
Update: The bug has been resolved.
As MS says in MSDN:
For improved performance, Microsoft Dynamics CRM caches plug-in
instances. The plug-in's Execute method should be written to be
stateless because the constructor is not called for every invocation
of the plug-in. Also, multiple system threads could execute the
plug-in at the same time. All per invocation state information is
stored in the context, so you should not use global variables or
attempt to store any data in member variables for use during the next
plug-in invocation...
https://msdn.microsoft.com/en-us/library/gg328263.aspx
Simply said do not use local variables in plugins.
If you're looking for autonumbering only than use an approach similar to this
https://www.linkedin.com/pulse/custom-auto-numbering-6-quick-steps-ms-dynamics-crm-eran-fuks