internal Activity CompileActivityAndSaveInCache(WorkflowJobDefinition definition, Activity activityTree, Dictionary <string, string> requiredAssemblies, out bool windowsWorkflow) { Activity activity = null; Func <WorkflowJobDefinition, bool> func = null; DefinitionCache.WorkflowDetails workflowDetail = new DefinitionCache.WorkflowDetails(); Activity activity1 = null; windowsWorkflow = false; string dependentAssemblyPath = definition.DependentAssemblyPath; string modulePath = definition.ModulePath; string[] array = definition.DependentWorkflows.ToArray(); Assembly assembly = null; string str = null; string xaml = definition.Xaml; if (activityTree == null) { if (!string.IsNullOrEmpty(xaml)) { object[] instanceId = new object[1]; instanceId[0] = definition.InstanceId; this._tracer.WriteMessage(string.Format(CultureInfo.InvariantCulture, "DefinitionCache: Caching activity for definition with instance ID: {0}. Xaml is passed", instanceId)); workflowDetail.ActivityTree = null; if (!string.IsNullOrEmpty(modulePath)) { string str1 = Environment.ExpandEnvironmentVariables(modulePath); string str2 = Environment.ExpandEnvironmentVariables("%windir%\\system32"); if (str1.IndexOf(str2, StringComparison.CurrentCultureIgnoreCase) != -1) { windowsWorkflow = true; } } if (definition.DependentAssemblyPath != null || (int)array.Length != 0) { activity1 = ImportWorkflowCommand.ConvertXamlToActivity(xaml, array, requiredAssemblies, ref dependentAssemblyPath, ref assembly, ref str); } else { activity1 = ImportWorkflowCommand.ConvertXamlToActivity(xaml); } } } else { object[] objArray = new object[1]; objArray[0] = definition.InstanceId; this._tracer.WriteMessage(string.Format(CultureInfo.InvariantCulture, "DefinitionCache: Caching activity for definition with instance ID: {0}. The activity Tree is passed.", objArray)); workflowDetail.ActivityTree = activityTree; activity1 = activityTree; } if (activity1 == null) { return(null); } else { workflowDetail.IsWindowsActivity = (sbyte)windowsWorkflow; workflowDetail.CompiledAssemblyPath = dependentAssemblyPath; workflowDetail.CompiledAssemblyName = str; lock (this._syncObject) { var keys = this._workflowDetailsCache.Keys; if (func == null) { func = (WorkflowJobDefinition item) => item.InstanceId == definition.InstanceId; } WorkflowJobDefinition workflowJobDefinition = keys.FirstOrDefault <WorkflowJobDefinition>(func); if (workflowJobDefinition != null) { this._workflowDetailsCache.Remove(definition); } this._workflowDetailsCache.Add(definition, workflowDetail); } if (this._cachedActivities.Count == 0x3e8) { this._cachedActivities.TryRemove(this._cachedActivities.Keys.ElementAt <WorkflowJobDefinition>(0), out activity); } this._cachedActivities.TryAdd(definition, activity1); return(activity1); } }
/// <summary> /// Compiles the activity and adds it to the cache before returning it. /// </summary> /// <param name="definition">WorkflowJobDefinition defined to represent a compiled activity.</param> /// <param name="activityTree">Activity Tree used for external activities</param> /// <param name="requiredAssemblies"></param> /// <param name="windowsWorkflow">indicates if the specified xaml is a Windows workflow</param> /// <param name="rootWorkflowName">Optional, once assigned, only root Workflow will be compiled</param> /// <returns>Activity compiled from xaml given, or retrieved from cache. /// Null if not found.</returns> internal Activity CompileActivityAndSaveInCache(WorkflowJobDefinition definition, Activity activityTree, Dictionary <string, string> requiredAssemblies, out bool windowsWorkflow, string rootWorkflowName = null) { WorkflowDetails workflowDetail = new WorkflowDetails(); Activity activity = null; // initialize windows workflow to false windowsWorkflow = false; string resultingCompiledAssemblyPath = definition.DependentAssemblyPath; string modulePath = definition.ModulePath; string[] dependentWorkflows = definition.DependentWorkflows.ToArray(); Assembly resultingCompiledAssembly = null; string resultingCompiledAssemblyName = null; string xaml = definition.Xaml; if (activityTree != null) { _tracer.WriteMessage(string.Format(CultureInfo.InvariantCulture, "DefinitionCache: Caching activity for definition with instance ID: {0}. The activity Tree is passed.", definition.InstanceId)); workflowDetail.ActivityTree = activityTree; activity = activityTree; } else if (!String.IsNullOrEmpty(xaml)) { // we need to read the xaml from the specified path and compile the same _tracer.WriteMessage(string.Format(CultureInfo.InvariantCulture, "DefinitionCache: Caching activity for definition with instance ID: {0}. Xaml is passed", definition.InstanceId)); workflowDetail.ActivityTree = null; // check if specified workflow is a windows workflow if (!string.IsNullOrEmpty(modulePath)) { string resolvedPath = Environment.ExpandEnvironmentVariables(modulePath); string resolvedWindowsPath = Environment.ExpandEnvironmentVariables(WindowsPath); if (resolvedPath.IndexOf(resolvedWindowsPath, StringComparison.CurrentCultureIgnoreCase) != -1) { windowsWorkflow = true; } } if (definition.DependentAssemblyPath == null && dependentWorkflows.Length == 0) { activity = ImportWorkflowCommand.ConvertXamlToActivity(xaml); } else { if (rootWorkflowName == null || (definition.Command == rootWorkflowName)) { activity = ImportWorkflowCommand.ConvertXamlToActivity(xaml, dependentWorkflows, requiredAssemblies, ref resultingCompiledAssemblyPath, ref resultingCompiledAssembly, ref resultingCompiledAssemblyName); } else { activity = ImportWorkflowCommand.ConvertXamlToActivity(xaml); } } } if (activity != null) { workflowDetail.IsWindowsActivity = windowsWorkflow; workflowDetail.CompiledAssemblyPath = resultingCompiledAssemblyPath; workflowDetail.CompiledAssemblyName = resultingCompiledAssemblyName; lock (_syncObject) { WorkflowJobDefinition definitionToRemove = _workflowDetailsCache.Keys.FirstOrDefault(item => item.InstanceId == definition.InstanceId); if (definitionToRemove != null) { _workflowDetailsCache.Remove(definition); } _workflowDetailsCache.Add(definition, workflowDetail); } // If cached activity count reaches _cacheSize, // Removing the cached activity at index 0 and adding the new activity to the activity cache, // Old logic was to clear 1000 cached activities and recompiling them again when needed. // if (_cachedActivities.Count == _cacheSize) { Activity removedActivity; _cachedActivities.TryRemove(_cachedActivities.Keys.ElementAt <WorkflowJobDefinition>(0), out removedActivity); } _cachedActivities.TryAdd(definition, activity); return(activity); } // we should never hit this point under normal course of operations return(null); }