我们之前写工作流宿主程序一般都是直接写在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
< string , object > ();
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();
}
}
public class WorkflowInstanceWrapper
{
private WorkflowInstance _workflowInstance;
private ManualResetEvent _waitHandle = new ManualResetEvent( false );
private Dictionary < String, Object > _outputParameters = new Dictionary
< string , object > ();
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( this , new WorkflowLogEventArgs(formattedMsg));
}
}
}
public class WorkflowLogEventArgs : EventArgs
{
private String _msg = String.Empty;
public WorkflowLogEventArgs(String msg)
{
_msg = msg;
}
public String Message
{
get { return _msg; }
}
{
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( this , new 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 < string , object > ();
wfArguments.Add( " InputString " , " one " );
WorkflowInstanceWrapper instance = manager.StartWorkflow(
typeof (SharedWorkflows.Workflow1), wfArguments);
instance.WorkflowInstance.Terminate( " Manually terminated " );
instance.WaitHandle.WaitOne( 10000 , false );
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();
= 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 < string , object > ();
wfArguments.Add( " InputString " , " one " );
WorkflowInstanceWrapper instance = manager.StartWorkflow(
typeof (SharedWorkflows.Workflow1), wfArguments);
instance.WorkflowInstance.Terminate( " Manually terminated " );
instance.WaitHandle.WaitOne( 10000 , false );
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](/images/cnblogs_com/carysun/WindowsLiveWriter/WF7_7B9E/1_thumb.jpg)
上一篇:
下一篇: