代码之家  ›  专栏  ›  技术社区  ›  CaffGeek

提高Windows工作流的速度

  •  2
  • CaffGeek  · 技术社区  · 14 年前

    我有下面的代码,让我执行一个工作流。这可以反复调用。而且经常是这样。它也生活在一个webservice中,因此可以同时有多个调用。这一点目前有效。但是它很慢,因为实例化 WorkflowRuntime 每次都很慢。

    我该如何改进?

    public class ApprovalWorkflowRunner : IApprovalWorkflowRunner
    {
        private static ILogger Logger { get; set; }
        private static IRepository Repository { get; set; }
    
        public ApprovalWorkflowRunner(ILogger logger, IRepository repository)
        {
            Logger = logger;
            Repository = repository;
        }
    
        public Request Execute(Action action)
        {
            var request = new Request();
    
            using (var workflowRuntime = new WorkflowRuntime())
            {
                workflowRuntime.StartRuntime();
                var waitHandle = new AutoResetEvent(false);
                workflowRuntime.WorkflowCompleted += ((sender, e) =>
                                                        {
                                                            waitHandle.Set();
                                                            request = e.OutputParameters["gRequest"] as Request;
                                                        });
                workflowRuntime.WorkflowTerminated += ((sender, e) =>
                                                        {
                                                            waitHandle.Set();
                                                            Logger.LogError(e.Exception, true, action.Serialize());
                                                        });
    
                var parameters = new Dictionary<string, object>
                                    {
                                        {"RepositoryInstance", Repository},
                                        {"RequestID", action.RequestID.ToString()},
                                        {"ActionCode", action.ToString()}
                                    };
    
                var instance = workflowRuntime.CreateWorkflow(typeof (ApprovalFlow), parameters);
                instance.Start();
                waitHandle.WaitOne();
            }
    
            return request;
        }
    }
    

    ……我是不是错过了一些简单的东西,很有可能我的大脑没有告诉我的身体它今天没有出现。

    2 回复  |  直到 14 年前
        1
  •  0
  •   Graham Clark    14 年前

    该页面显示了WorkflowRuntime工厂的一些代码,我将在下面介绍这些代码,我相信这些代码最初是从WindowsWorkflowFoundation一步一步的书中获得的

    public static class WorkflowFactory
    {
        // Singleton instance of the workflow runtime
        private static WorkflowRuntime _workflowRuntime = null;
    
        // Lock (sync) object
        private static object _syncRoot = new object();
    
        /// <summary>
        /// Factory method
        /// </summary>
        /// <returns></returns>
        public static WorkflowRuntime GetWorkflowRuntime()
        {
            // Lock execution thread in case of multi-threaded
            // (concurrent) access.
            lock (_syncRoot)
            {
                // Check for startup condition
                if (null == _workflowRuntime)
                {
                    // Provide for shutdown
                    AppDomain.CurrentDomain.ProcessExit += new EventHandler(StopWorkflowRuntime);
                    AppDomain.CurrentDomain.DomainUnload += new EventHandler(StopWorkflowRuntime);
    
                    // Not started, so create instance
                    _workflowRuntime = new WorkflowRuntime();
    
                    // Start the runtime
                    _workflowRuntime.StartRuntime();
                } // if
    
                // Return singleton instance
                return _workflowRuntime;
            } // lock
        }
    
        // Shutdown method
        static void StopWorkflowRuntime(object sender, EventArgs e)
        {
            if (_workflowRuntime != null)
            {
                if (_workflowRuntime.IsStarted)
                {
                    try
                    {
                        // Stop the runtime
                        _workflowRuntime.StopRuntime();
                    }
                    catch (ObjectDisposedException)
                    {
                        // Already disposed of, so ignore...
                    } // catch
                } // if
            } // if
        }
    }
    

    WorkflowFactory.GetWorkflowRuntime();
    

    编辑: 好的,对不起。您可以尝试检查实例是否是您期望的实例,如果不是,则返回。请注意,这段代码是未经测试的,只是试图让大家了解这个想法。

    public class ApprovalWorkflowRunner : IApprovalWorkflowRunner
    {
        private static ILogger Logger { get; set; }
        private static IRepository Repository { get; set; }
    
        public ApprovalWorkflowRunner(ILogger logger, IRepository repository)
        {
            Logger = logger;
            Repository = repository;
        }
    
        public Request Execute(Action action)
        {
            var request = new Request();
    
            var workflowRuntime = WorkflowFactory.GetWorkflowRuntime();
    
            workflowRuntime.StartRuntime();
            var waitHandle = new AutoResetEvent(false);
            WorkflowInstance instance = null;
            workflowRuntime.WorkflowCompleted += ((sender, e) =>
                                                    {
                                                        if (e.WorkflowInstance != instance) return;
                                                        waitHandle.Set();
                                                        request = e.OutputParameters["gRequest"] as Request;
                                                    });
            workflowRuntime.WorkflowTerminated += ((sender, e) =>
                                                    {
                                                        if (e.WorkflowInstance != instance) return;
                                                        waitHandle.Set();
                                                        Logger.LogError(e.Exception, true, action.Serialize());
                                                    });
    
            var parameters = new Dictionary<string, object>
                                {
                                    {"RepositoryInstance", Repository},
                                    {"RequestID", action.RequestID.ToString()},
                                    {"ActionCode", action.ToString()}
                                };
    
            instance = workflowRuntime.CreateWorkflow(typeof (ApprovalFlow), parameters);
            instance.Start();
            waitHandle.WaitOne();
    
            return request;
        }
    }
    
        2
  •  0
  •   Steve Ellinger    14 年前

    我能想到的提高代码速度的最简单的方法是将WorkflowRuntime实例中的ValidateOnCreate属性设置为false。默认情况下,它设置为true,这意味着每次创建工作流实例时。我假设您的工作流是静态的,因为您没有在运行时对它进行动态更改,而是在编译时定义了它。如果是这种情况,您应该能够跳过验证步骤。根据您的工作流程有多复杂,这可能会显著提高代码的速度。

    假设这并不能提高足够的速度,其他建议如下。使ApprovalWorkflowRunner类的Execute方法实例中使用的WaitHandle、Request和Workflow对象成为成员。WorkflowRuntime将是Execute方法的一个参数。在执行此操作时,您应该在每次希望运行ApprovalFlow工作流时创建ApprovalWorkflowRunner类的新实例。然后,您的Execute方法应该如下所示:

        public Request Execute(Action action, WorkflowRuntime workflowRuntime) {
                workflowRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(workflowRuntime_WorkflowCompleted);
                workflowRuntime.WorkflowTerminated += new EventHandler<WorkflowTerminatedEventArgs>(workflowRuntime_WorkflowTerminated);
    
                var parameters = new Dictionary<string, object>
                            {
                                {"RepositoryInstance", Repository},
                                {"RequestID", action.RequestID.ToString()},
                                {"ActionCode", action.ToString()}
                            };
    
                mWorkflowInstance = workflowRuntime.CreateWorkflow(typeof(ApprovalFlow), parameters);
                mWorkflowInstance.Start();
                mWaitHandle.WaitOne();
    
            return mRequest;
        }
    

        void workflowRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e) {
            if (!e.WorkflowInstance.Equals(mWorkflowInstance)) return;
            mRequest = e.OutputParameters["gRequest"] as Request;
            mWaitHandle.Set();
            return;
        }
    

    请注意,我已经将处理程序中的两行从代码中的方式切换过来,设置了等待句柄 分配请求实例将创建竞争条件。

    最后一点注意:对WorkflowRuntime实例调用Dispose方法显然必须在代码的其他地方进行;但是Microsoft建议在调用Dispose之前调用StopRuntime方法: Remarks: shut down the WorkflowRuntime gracefully