• 坚持学习WF(6):开发可复用的宿主程序


    我们之前写工作流宿主程序一般都是直接写在program.cs文件里,这样复用性比较差。我们就简单的写两个类,这两个类主要实现的是对WorkflowInstance和WorkflowRuntime的封装。我们以后的例子都会使用这两个类。

    第一个类是WorkflowInstanceWrapper,代码如下:

    [Serializable]
        
    public class WorkflowInstanceWrapper
        {
            
    private WorkflowInstance _workflowInstance;
            
    private ManualResetEvent _waitHandle = new ManualResetEvent(false);
            
    private Dictionary<String, Object> _outputParameters= new Dictionary
                    <stringobject>();
            
    private Exception _exception;
            
    private String _reasonSuspended = String.Empty;

            
    public WorkflowInstanceWrapper(WorkflowInstance instance)
            {
                _workflowInstance 
    = instance;
            }        
            
    public Guid Id
            {
                
    get
                {
                    
    if (_workflowInstance != null)
                       
    return _workflowInstance.InstanceId;
                    
    else
                       
    return Guid.Empty;
                }
            }        
            
    public Dictionary<String, Object> OutputParameters
            {
                
    get { return _outputParameters; }
                
    set { _outputParameters = value; }
            }        
            
    public ManualResetEvent WaitHandle
            {
                
    get { return _waitHandle; }
                
    set { _waitHandle = value; }
            }        
            
    public Exception Exception
            {
                
    get { return _exception; }
                
    set { _exception = value; }
            }        
            
    public String ReasonSuspended
            {
                
    get { return _reasonSuspended; }
                
    set { _reasonSuspended = value; }
            }        
            
    public WorkflowInstance WorkflowInstance
            {
                
    get { return _workflowInstance; }
            }        
            
    public void StopWaiting()
            {
                _waitHandle.Set();
            }
        }

    1._exception,_reasonSuspended:表示当工作流非正常终止或挂起时的相关信息。
    2. OutputParameters:用来接收工作流的输出参数,工作流运行时引擎将引发 WorkflowCompleted事件。
    工作流运行时引擎将在WorkflowCompletedEventArgs 中传入工作流的所有输出参数。 这些参数包括工作
    流的 out 和 ref 参数。
     

    第二类是WorkflowManager代码如下:  

     public class WorkflowRuntimeManager : IDisposable
        {
            
    private WorkflowRuntime _workflowRuntime;
            
    private Dictionary<Guid, WorkflowInstanceWrapper> _workflows
                                   = new Dictionary<Guid, WorkflowInstanceWrapper>();
          
            
    public WorkflowRuntimeManager(WorkflowRuntime instance)
            {
                _workflowRuntime 
    = instance;
                
    if (instance == null)
                {
                    
    throw new NullReferenceException(
                        
    "A non-null WorkflowRuntime instance is required");
                }            
                SubscribeToEvents(instance);
            }

          
            
    public WorkflowInstanceWrapper StartWorkflow(Type workflowType,
                Dictionary
    <String, Object> parameters)
            {
                WorkflowInstance instance 
    = _workflowRuntime.CreateWorkflow(
                    workflowType, parameters);
                WorkflowInstanceWrapper wrapper
                    
    = AddWorkflowInstance(instance);
                instance.Start();
                
    return wrapper;
            }
            
            
    public WorkflowInstanceWrapper StartWorkflow(String markupFileName,
                String rulesMarkupFileName,
                Dictionary
    <String, Object> parameters)
            {
                WorkflowInstance instance 
    = null;
                WorkflowInstanceWrapper wrapper 
    = null;
                XmlReader wfReader 
    = null;
                XmlReader rulesReader 
    = null;
                
    try
                {
                    wfReader 
    = XmlReader.Create(markupFileName);
                    
    if (!String.IsNullOrEmpty(rulesMarkupFileName))
                    {
                        rulesReader 
    = XmlReader.Create(rulesMarkupFileName);
                        instance 
    = _workflowRuntime.CreateWorkflow( wfReader, rulesReader, parameters);
                    }
                    
    else
                    {
                        instance 
    = _workflowRuntime.CreateWorkflow(wfReader, null, parameters);
                    }
                    wrapper 
    = AddWorkflowInstance(instance);
                    instance.Start();
                }
                
    finally
                {
                    
    if (wfReader != null)
                    {
                        wfReader.Close();
                    }
                    
    if (rulesReader != null)
                    {
                        rulesReader.Close();
                    }
                }
                
    return wrapper;
            }

           
    public WorkflowRuntime WorkflowRuntime
            {
                
    get { return _workflowRuntime; }
            }        
            
    public Dictionary<Guid, WorkflowInstanceWrapper> Workflows
            {
                
    get { return _workflows; }
            }        
            
    public event EventHandler<WorkflowLogEventArgs> MessageEvent;    

           
            
    public void ClearWorkflow(Guid workflowId)
            {
                
    if (_workflows.ContainsKey(workflowId))
                {
                    _workflows.Remove(workflowId);
                }
            }
          
            
    public void ClearAllWorkflows()
            {
                _workflows.Clear();
            }
           
            
    private WorkflowInstanceWrapper AddWorkflowInstance(
                WorkflowInstance instance)
            {
                WorkflowInstanceWrapper wrapper 
    = null;
                
    if (!_workflows.ContainsKey(instance.InstanceId))
                {
                    wrapper 
    = new WorkflowInstanceWrapper(instance);
                    _workflows.Add(wrapper.Id, wrapper);
                }
                
    return wrapper;
            }
         
            
    public WorkflowInstanceWrapper FindWorkflowInstance(Guid workflowId)
            {
                WorkflowInstanceWrapper result 
    = null;
                
    if (_workflows.ContainsKey(workflowId))
                {
                    result 
    = _workflows[workflowId];
                }
                
    return result;
            }
           
            
    public void WaitAll(Int32 msecondsTimeout)
            {
                
    if (_workflows.Count > 0)
                {
                    WaitHandle[] handles 
    = new WaitHandle[_workflows.Count];
                    Int32 index 
    = 0;
                    
    foreach (WorkflowInstanceWrapper wrapper
                        
    in _workflows.Values)
                    {
                        handles[index] 
    = wrapper.WaitHandle;
                        index
    ++;
                    }
                    WaitHandle.WaitAll(handles, msecondsTimeout, 
    false);
                }
            }
         
            
    public void Dispose()
            {
                
    if (_workflowRuntime != null)
                {
                    _workflowRuntime.StopRuntime();
                    _workflowRuntime.Dispose();
                }
                ClearAllWorkflows();
            }
          
            
    private void SubscribeToEvents(WorkflowRuntime runtime)
            {
                runtime.Started 
    += new EventHandler<WorkflowRuntimeEventArgs>( runtime_Started);
                runtime.Stopped 
    += new EventHandler<WorkflowRuntimeEventArgs>(runtime_Stopped);
                runtime.WorkflowAborted
    += ......
                runtime.WorkflowCompleted
    += ......
                runtime.WorkflowCreated += ......   
                ............
            }

            
    void runtime_Started(object sender, WorkflowRuntimeEventArgs e)
            {
                LogStatus(Guid.Empty, 
    "Started");
            }
            
    void runtime_Stopped(object sender, WorkflowRuntimeEventArgs e)
            {
                LogStatus(Guid.Empty, 
    "Stopped");
            }
            
    void runtime_WorkflowCreated(object sender, WorkflowEventArgs e)
            {
                LogStatus(e.WorkflowInstance.InstanceId, 
    "WorkflowCreated");
            }
            
    void runtime_WorkflowStarted(object sender, WorkflowEventArgs e)
            {
                LogStatus(e.WorkflowInstance.InstanceId, 
    "WorkflowStarted");
            }
            
    void runtime_WorkflowIdled(object sender, WorkflowEventArgs e)
            {
                LogStatus(e.WorkflowInstance.InstanceId, 
    "WorkflowIdled");
            }

            
    void runtime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
            {
                LogStatus(e.WorkflowInstance.InstanceId, 
    "WorkflowCompleted");
                WorkflowInstanceWrapper wrapper
                    
    = FindWorkflowInstance(e.WorkflowInstance.InstanceId);
                
    if (wrapper != null)
                {
                    wrapper.OutputParameters 
    = e.OutputParameters;
                    wrapper.StopWaiting();
                }
            }

            
    void runtime_WorkflowTerminated(object sender,
                WorkflowTerminatedEventArgs e)
            {
                LogStatus(e.WorkflowInstance.InstanceId, 
    "WorkflowTerminated");
                WorkflowInstanceWrapper wrapper 
    = FindWorkflowInstance(e.WorkflowInstance.InstanceId);
                
    if (wrapper != null)
                {
                    wrapper.Exception 
    = e.Exception;
                    wrapper.StopWaiting();
                }
            }

            
    void runtime_WorkflowSuspended(object sender, WorkflowSuspendedEventArgs e)
            {
                LogStatus(e.WorkflowInstance.InstanceId, 
    "WorkflowSuspended");
                WorkflowInstanceWrapper wrapper 
    = FindWorkflowInstance(e.WorkflowInstance.InstanceId);
                
    if (wrapper != null)
                {
                    wrapper.ReasonSuspended 
    = e.Error;
                }
            }

            
    void runtime_WorkflowResumed(object sender, WorkflowEventArgs e)
            {
                LogStatus(e.WorkflowInstance.InstanceId, 
    "WorkflowResumed");
            }
            
    void runtime_WorkflowPersisted(object sender, WorkflowEventArgs e)
            {
                LogStatus(e.WorkflowInstance.InstanceId, 
    "WorkflowPersisted");
            }
            
    void runtime_WorkflowLoaded(object sender, WorkflowEventArgs e)
            {
                LogStatus(e.WorkflowInstance.InstanceId, 
    "WorkflowLoaded");
            }
            
    void runtime_WorkflowAborted(object sender, WorkflowEventArgs e)
            {
                LogStatus(e.WorkflowInstance.InstanceId, 
    "WorkflowAborted");
                WorkflowInstanceWrapper wrapper
                    
    = FindWorkflowInstance(e.WorkflowInstance.InstanceId);
                
    if (wrapper != null)
                {
                    wrapper.StopWaiting();
                }
            }

            
    void runtime_WorkflowUnloaded(object sender, WorkflowEventArgs e)
            {
                LogStatus(e.WorkflowInstance.InstanceId, 
    "WorkflowUnloaded");
            }

            
    private void LogStatus(Guid instanceId, String msg)
            {
                
    if (MessageEvent != null)
                {
                    String formattedMsg;
                    
    if (instanceId == Guid.Empty)
                    {
                        formattedMsg 
    = String.Format("Runtime - {0}", msg);
                    }
                    
    else
                    {
                        formattedMsg 
    = String.Format("{0} - {1}", instanceId, msg);
                    }
                    
    //raise the event
                    MessageEvent(thisnew WorkflowLogEventArgs(formattedMsg));
                }
            }

        }   
        
    public class WorkflowLogEventArgs : EventArgs
        {
            
    private String _msg = String.Empty;
            
    public WorkflowLogEventArgs(String msg)
            {
                _msg 
    = msg;
            }

            
    public String Message
            {
                
    get { return _msg; }
            }

    1._workflows:一个key为Guid,value为WorkflowInstanceWrapper的字典。
    2.SubscribeToEvent():给workflowRuntime订阅事件.
    3.StartWorkflow():实现创建,开始工作流.
    4.MessageEvent:对Message进行格式化。
    5.WaitAll()用来挂起当前的线程直到所有的workflows完成,每个WorkflowInstanceWrapper有一个WaitHandle属性以便宿主程序能灵活控制。 

    下面是测试代码:
    using (WorkflowRuntimeManager manager
            
    = new WorkflowRuntimeManager(new WorkflowRuntime("WorkflowRuntime")))
    {
       manager.MessageEvent 
    += delegate(Object sender, WorkflowLogEventArgs e)
       {
          Console.WriteLine(e.Message);
       };
       manager.WorkflowRuntime.StartRuntime();
       Dictionary
    <String, Object> wfArguments= new Dictionary<stringobject>();
       wfArguments.Add(
    "InputString""one");
       WorkflowInstanceWrapper instance 
    = manager.StartWorkflow(
               
    typeof(SharedWorkflows.Workflow1), wfArguments);
       instance.WorkflowInstance.Terminate(
    "Manually terminated");
       instance.WaitHandle.WaitOne(
    10000false);
       
    foreach (WorkflowInstanceWrapper wrapperin manager.Workflows.Values)
       {
           
    if (wrapper.OutputParameters.ContainsKey("Result"))
           {
                Console.WriteLine(wrapper.OutputParameters[
    "Result"]);
           }
           
    if (wrapper.Exception != null)
           {
         Console.WriteLine(
    "{0}-Exception:{1}",wrapper.Id,wrapper.Exception.Message);
           }
           
    if (wrapper.ReasonSuspended.Length > 0)
           {
        Console.WriteLine(
    "{0}-Suspended: {1}",wrapper.Id, wrapper.ReasonSuspended);
           }
    }    manager.ClearAllWorkflows();























    下面运行结果,从该结果可以清晰的看出工作流的执行过程:


    1
     上一篇:坚持学习WF(5):自定义活动(CustomActivity) 
    下一篇:坚持学习WF(7):流程控制(Flow Control)
    作者:生鱼片
             
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    javascript中数组去重的4种方法
    dede使用方法----实现英文版的搜索功能
    dede去掉当前位置position后面的箭头
    dede使用方法----如何转换时间戳
    Python字符串、元组、列表、字典互相转换的方法
    Python 列表的操作
    Python 元祖的操作
    Python 操作文件、文件夹、目录大全
    python文件目录操作大全
    python用time函数计算程序运行时间
  • 原文地址:https://www.cnblogs.com/carysun/p/1164609.html
Copyright © 2020-2023  润新知