首页 > 编程开发 > Objective-C编程 >
-
坚持学习WF6开发可复用的突宿主程序
我们之前写工作流宿主程序一般都是直接写在program.cs文件里,这样复用性比较差。我们就简单的写两个类,这两个类主要实现的是对WorkflowInstance和WorkflowRuntime的封装。我们以后的例子都会使用这两个类。
第一个类是WorkflowInstanceWrapper,代码如下:
[Serializable]
publicclassWorkflowInstanceWrapper
{
privateWorkflowInstance_workflowInstance;
privateManualResetEvent_waitHandle=newManualResetEvent(false);
privateDictionary<String,Object>_outputParameters=newDictionary
<string,object>();
privateException_exception;
privateString_reasonSuspended=String.Empty;
publicWorkflowInstanceWrapper(WorkflowInstanceinstance)
{
_workflowInstance=instance;
}
publicGuidId
{
get
{
if(_workflowInstance!=null)
return_workflowInstance.InstanceId;
else
returnGuid.Empty;
}
}
publicDictionary<String,Object>OutputParameters
{
get{return_outputParameters;}
set{_outputParameters=value;}
}
publicManualResetEventWaitHandle
{
get{return_waitHandle;}
set{_waitHandle=value;}
}
publicExceptionException
{
get{return_exception;}
set{_exception=value;}
}
publicStringReasonSuspended
{
get{return_reasonSuspended;}
set{_reasonSuspended=value;}
}
publicWorkflowInstanceWorkflowInstance
{
get{return_workflowInstance;}
}
publicvoidStopWaiting()
{
_waitHandle.Set();
}
}
1._exception,_reasonSuspended:表示当工作流非正常终止或挂起时的相关信息。
2. OutputParameters:用来接收工作流的输出参数,工作流运行时引擎将引发 WorkflowCompleted事件。
工作流运行时引擎将在WorkflowCompletedEventArgs 中传入工作流的所有输出参数。 这些参数包括工作
流的 out 和 ref 参数。
第二类是WorkflowManager代码如下:
publicclassWorkflowRuntimeManager:IDisposable
{
privateWorkflowRuntime_workflowRuntime;
privateDictionary<Guid,WorkflowInstanceWrapper>_workflows
=newDictionary<Guid,WorkflowInstanceWrapper>();
publicWorkflowRuntimeManager(WorkflowRuntimeinstance)
{
_workflowRuntime=instance;
if(instance==null)
{
thrownewNullReferenceException(
"Anon-nullWorkflowRuntimeinstanceisrequired");
}
SubscribeToEvents(instance);
}
publicWorkflowInstanceWrapperStartWorkflow(TypeworkflowType,
Dictionary<String,Object>parameters)
{
WorkflowInstanceinstance=_workflowRuntime.CreateWorkflow(
workflowType,parameters);
WorkflowInstanceWrapperwrapper
=AddWorkflowInstance(instance);
instance.Start();
returnwrapper;
}
publicWorkflowInstanceWrapperStartWorkflow(StringmarkupFileName,
StringrulesMarkupFileName,
Dictionary<String,Object>parameters)
{
WorkflowInstanceinstance=null;
WorkflowInstanceWrapperwrapper=null;
XmlReaderwfReader=null;
XmlReaderrulesReader=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();
}
}
returnwrapper;
}
publicWorkflowRuntimeWorkflowRuntime
{
get{return_workflowRuntime;}
}
publicDictionary<Guid,WorkflowInstanceWrapper>Workflows
{
get{return_workflows;}
}
publiceventEventHandler<WorkflowLogEventArgs>MessageEvent;
publicvoidClearWorkflow(GuidworkflowId)
{
if(_workflows.ContainsKey(workflowId))
{
_workflows.Remove(workflowId);
}
}
publicvoidClearAllWorkflows()
{
_workflows.Clear();
}
privateWorkflowInstanceWrapperAddWorkflowInstance(
WorkflowInstanceinstance)
{
WorkflowInstanceWrapperwrapper=null;
if(!_workflows.ContainsKey(instance.InstanceId))
{
wrapper=newWorkflowInstanceWrapper(instance);
_workflows.Add(wrapper.Id,wrapper);
}
returnwrapper;
}
publicWorkflowInstanceWrapperFindWorkflowInstance(GuidworkflowId)
{
WorkflowInstanceWrapperresult=null;
if(_workflows.ContainsKey(workflowId))
{
result=_workflows[workflowId];
}
returnresult;
}
publicvoidWaitAll(Int32msecondsTimeout)
{
if(_workflows.Count>0)
{
WaitHandle[]handles=newWaitHandle[_workflows.Count];
Int32index=0;
foreach(WorkflowInstanceWrapperwrapper
in_workflows.Values)
{
handles[index]=wrapper.WaitHandle;
index++;
}
WaitHandle.WaitAll(handles,msecondsTimeout,false);
}
}
publicvoidDispose()
{
if(_workflowRuntime!=null)
{
_workflowRuntime.StopRuntime();
_workflowRuntime.Dispose();
}
ClearAllWorkflows();
}
privatevoidSubscribeToEvents(WorkflowRuntimeruntime)
{
runtime.Started+=newEventHandler<WorkflowRuntimeEventArgs>(runtime_Started);
runtime.Stopped+=newEventHandler<WorkflowRuntimeEventArgs>(runtime_Stopped);
runtime.WorkflowAborted+=......
runtime.WorkflowCompleted+=......
runtime.WorkflowCreated+=......
............
}
voidruntime_Started(objectsender,WorkflowRuntimeEventArgse)
{
LogStatus(Guid.Empty,"Started");
}
voidruntime_Stopped(objectsender,WorkflowRuntimeEventArgse)
{
LogStatus(Guid.Empty,"Stopped");
}
voidruntime_WorkflowCreated(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowCreated");
}
voidruntime_WorkflowStarted(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowStarted");
}
voidruntime_WorkflowIdled(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowIdled");
}
voidruntime_WorkflowCompleted(objectsender,WorkflowCompletedEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowCompleted");
WorkflowInstanceWrapperwrapper
=FindWorkflowInstance(e.WorkflowInstance.InstanceId);
if(wrapper!=null)
{
wrapper.OutputParameters=e.OutputParameters;
wrapper.StopWaiting();
}
}
voidruntime_WorkflowTerminated(objectsender,
WorkflowTerminatedEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowTerminated");
WorkflowInstanceWrapperwrapper=FindWorkflowInstance(e.WorkflowInstance.InstanceId);
if(wrapper!=null)
{
wrapper.Exception=e.Exception;
wrapper.StopWaiting();
}
}
voidruntime_WorkflowSuspended(objectsender,WorkflowSuspendedEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowSuspended");
WorkflowInstanceWrapperwrapper=FindWorkflowInstance(e.WorkflowInstance.InstanceId);
if(wrapper!=null)
{
wrapper.ReasonSuspended=e.Error;
}
}
voidruntime_WorkflowResumed(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowResumed");
}
voidruntime_WorkflowPersisted(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowPersisted");
}
voidruntime_WorkflowLoaded(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowLoaded");
}
voidruntime_WorkflowAborted(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowAborted");
WorkflowInstanceWrapperwrapper
=FindWorkflowInstance(e.WorkflowInstance.InstanceId);
if(wrapper!=null)
{
wrapper.StopWaiting();
}
}
voidruntime_WorkflowUnloaded(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowUnloaded");
}
privatevoidLogStatus(GuidinstanceId,Stringmsg)
{
if(MessageEvent!=null)
{
StringformattedMsg;
if(instanceId==Guid.Empty)
{
formattedMsg=String.Format("Runtime-{0}",msg);
}
else
{
formattedMsg=String.Format("{0}-{1}",instanceId,msg);
}
//raisetheevent
MessageEvent(this,newWorkflowLogEventArgs(formattedMsg));
}
}
}
publicclassWorkflowLogEventArgs:EventArgs
{
privateString_msg=String.Empty;
publicWorkflowLogEventArgs(Stringmsg)
{
_msg=msg;
}
publicStringMessage
{
get{return_msg;}
}
1._workflows:一个key为Guid,value为WorkflowInstanceWrapper的字典。
2.SubscribeToEvent():给workflowRuntime订阅事件.
3.StartWorkflow():实现创建,开始工作流.
4.MessageEvent:对Message进行格式化。
5.WaitAll()用来挂起当前的线程直到所有的workflows完成,每个WorkflowInstanceWrapper有一个WaitHandle属性以便宿主程序能灵活控制。
下面是测试代码:
using(WorkflowRuntimeManagermanager
=newWorkflowRuntimeManager(newWorkflowRuntime("WorkflowRuntime")))
{
manager.MessageEvent+=delegate(Objectsender,WorkflowLogEventArgse)
{
Console.WriteLine(e.Message);
};
manager.WorkflowRuntime.StartRuntime();
Dictionary<String,Object>wfArguments=newDictionary<string,object>();
wfArguments.Add("InputString","one");
WorkflowInstanceWrapperinstance=manager.StartWorkflow(
typeof(SharedWorkflows.Workflow1),wfArguments);
instance.WorkflowInstance.Terminate("Manuallyterminated");
instance.WaitHandle.WaitOne(10000,false);
foreach(WorkflowInstanceWrapperwrapperinmanager.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._exception,_reasonSuspended:表示当工作流非正常终止或挂起时的相关信息。
2. OutputParameters:用来接收工作流的输出参数,工作流运行时引擎将引发 WorkflowCompleted事件。
工作流运行时引擎将在WorkflowCompletedEventArgs 中传入工作流的所有输出参数。 这些参数包括工作
流的 out 和 ref 参数。
第二类是WorkflowManager代码如下:
publicclassWorkflowRuntimeManager:IDisposable
{
privateWorkflowRuntime_workflowRuntime;
privateDictionary<Guid,WorkflowInstanceWrapper>_workflows
=newDictionary<Guid,WorkflowInstanceWrapper>();
publicWorkflowRuntimeManager(WorkflowRuntimeinstance)
{
_workflowRuntime=instance;
if(instance==null)
{
thrownewNullReferenceException(
"Anon-nullWorkflowRuntimeinstanceisrequired");
}
SubscribeToEvents(instance);
}
publicWorkflowInstanceWrapperStartWorkflow(TypeworkflowType,
Dictionary<String,Object>parameters)
{
WorkflowInstanceinstance=_workflowRuntime.CreateWorkflow(
workflowType,parameters);
WorkflowInstanceWrapperwrapper
=AddWorkflowInstance(instance);
instance.Start();
returnwrapper;
}
publicWorkflowInstanceWrapperStartWorkflow(StringmarkupFileName,
StringrulesMarkupFileName,
Dictionary<String,Object>parameters)
{
WorkflowInstanceinstance=null;
WorkflowInstanceWrapperwrapper=null;
XmlReaderwfReader=null;
XmlReaderrulesReader=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();
}
}
returnwrapper;
}
publicWorkflowRuntimeWorkflowRuntime
{
get{return_workflowRuntime;}
}
publicDictionary<Guid,WorkflowInstanceWrapper>Workflows
{
get{return_workflows;}
}
publiceventEventHandler<WorkflowLogEventArgs>MessageEvent;
publicvoidClearWorkflow(GuidworkflowId)
{
if(_workflows.ContainsKey(workflowId))
{
_workflows.Remove(workflowId);
}
}
publicvoidClearAllWorkflows()
{
_workflows.Clear();
}
privateWorkflowInstanceWrapperAddWorkflowInstance(
WorkflowInstanceinstance)
{
WorkflowInstanceWrapperwrapper=null;
if(!_workflows.ContainsKey(instance.InstanceId))
{
wrapper=newWorkflowInstanceWrapper(instance);
_workflows.Add(wrapper.Id,wrapper);
}
returnwrapper;
}
publicWorkflowInstanceWrapperFindWorkflowInstance(GuidworkflowId)
{
WorkflowInstanceWrapperresult=null;
if(_workflows.ContainsKey(workflowId))
{
result=_workflows[workflowId];
}
returnresult;
}
publicvoidWaitAll(Int32msecondsTimeout)
{
if(_workflows.Count>0)
{
WaitHandle[]handles=newWaitHandle[_workflows.Count];
Int32index=0;
foreach(WorkflowInstanceWrapperwrapper
in_workflows.Values)
{
handles[index]=wrapper.WaitHandle;
index++;
}
WaitHandle.WaitAll(handles,msecondsTimeout,false);
}
}
publicvoidDispose()
{
if(_workflowRuntime!=null)
{
_workflowRuntime.StopRuntime();
_workflowRuntime.Dispose();
}
ClearAllWorkflows();
}
privatevoidSubscribeToEvents(WorkflowRuntimeruntime)
{
runtime.Started+=newEventHandler<WorkflowRuntimeEventArgs>(runtime_Started);
runtime.Stopped+=newEventHandler<WorkflowRuntimeEventArgs>(runtime_Stopped);
runtime.WorkflowAborted+=......
runtime.WorkflowCompleted+=......
runtime.WorkflowCreated+=......
............
}
voidruntime_Started(objectsender,WorkflowRuntimeEventArgse)
{
LogStatus(Guid.Empty,"Started");
}
voidruntime_Stopped(objectsender,WorkflowRuntimeEventArgse)
{
LogStatus(Guid.Empty,"Stopped");
}
voidruntime_WorkflowCreated(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowCreated");
}
voidruntime_WorkflowStarted(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowStarted");
}
voidruntime_WorkflowIdled(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowIdled");
}
voidruntime_WorkflowCompleted(objectsender,WorkflowCompletedEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowCompleted");
WorkflowInstanceWrapperwrapper
=FindWorkflowInstance(e.WorkflowInstance.InstanceId);
if(wrapper!=null)
{
wrapper.OutputParameters=e.OutputParameters;
wrapper.StopWaiting();
}
}
voidruntime_WorkflowTerminated(objectsender,
WorkflowTerminatedEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowTerminated");
WorkflowInstanceWrapperwrapper=FindWorkflowInstance(e.WorkflowInstance.InstanceId);
if(wrapper!=null)
{
wrapper.Exception=e.Exception;
wrapper.StopWaiting();
}
}
voidruntime_WorkflowSuspended(objectsender,WorkflowSuspendedEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowSuspended");
WorkflowInstanceWrapperwrapper=FindWorkflowInstance(e.WorkflowInstance.InstanceId);
if(wrapper!=null)
{
wrapper.ReasonSuspended=e.Error;
}
}
voidruntime_WorkflowResumed(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowResumed");
}
voidruntime_WorkflowPersisted(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowPersisted");
}
voidruntime_WorkflowLoaded(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowLoaded");
}
voidruntime_WorkflowAborted(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowAborted");
WorkflowInstanceWrapperwrapper
=FindWorkflowInstance(e.WorkflowInstance.InstanceId);
if(wrapper!=null)
{
wrapper.StopWaiting();
}
}
voidruntime_WorkflowUnloaded(objectsender,WorkflowEventArgse)
{
LogStatus(e.WorkflowInstance.InstanceId,"WorkflowUnloaded");
}
privatevoidLogStatus(GuidinstanceId,Stringmsg)
{
if(MessageEvent!=null)
{
StringformattedMsg;
if(instanceId==Guid.Empty)
{
formattedMsg=String.Format("Runtime-{0}",msg);
}
else
{
formattedMsg=String.Format("{0}-{1}",instanceId,msg);
}
//raisetheevent
MessageEvent(this,newWorkflowLogEventArgs(formattedMsg));
}
}
}
publicclassWorkflowLogEventArgs:EventArgs
{
privateString_msg=String.Empty;
publicWorkflowLogEventArgs(Stringmsg)
{
_msg=msg;
}
publicStringMessage
{
get{return_msg;}
}