坚持学习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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值