Plug-in assemblies: Difference between revisions

Jump to navigation Jump to search
 
Line 119: Line 119:


When you fetch data but don't use the result, you can encounter the exception <code>System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first</code>. To avoid this problem, make sure that all fetch results are used.
When you fetch data but don't use the result, you can encounter the exception <code>System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first</code>. To avoid this problem, make sure that all fetch results are used.
== Example: Schedule a workflow ==
One of the possible use cases is to schedule a job with a delay. For example, you have a trigger that executes when a new account record is created. You don't want to perform the follow-up action immediately but after a delay.
Use the following sample to schedule the job.
<syntaxhighlight lang="js">
protected void ScheduleJob()
{
    // schedule job
    var processService = this.Context.GetService(typeof(IPluginProcessService)) as IPluginProcessService;
    if (processService != null)
    {
        var job = new PluginScheduleJob();
        job.Name = $"Scheduled Test Job";
        job.RegardingObjectId = new XRMServer.Data.EntityReference(Guid.NewGuid(), "account");
        job.TriggerAt = DateTime.Now.AddMinutes(1);
        job.TypeName = typeof(Fieldiu.Plugins.accountP).FullName;
        job.Data = this.SerializeData(data);
        processService.ScheduleJob(job);
    }
}
</syntaxhighlight>
To send data for the job, use the following line:
<syntaxhighlight lang="js">
job.Data = this.SerializeData(data);
</syntaxhighlight>
In the scheduled job, this is how you can retrieve the data as the input parameter:
<syntaxhighlight lang="js">
object userData;
if (!this.Context.InputParameters.TryGetValue(PluginInputParameterName.UserData, out userData))
return PluginResult.Canceled;
var mySerializedData = (string)userData;
</syntaxhighlight>
A similar solution can also be useful for long-running jobs. In that case, replace <code>TriggerAt</code> with <code>job.Recurrence = processService.GetRecurrence(0, 1);</code>. Keep in mind that long-running jobs (e.g., when generating some statistics) must be stopped after 5 minutes (or they will be aborted by the system). Return <code>PluginResult.InProgress</code>. Store the current state into data: <code>this.Context.InputParameters[PluginInputParameterName.UserData] = this.SerializeBatchData(result, entity);</code>. When everything is complete, return <code>PluginResult.Succeeded;</code>




Navigation menu