`

坚持学习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)
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics