尝试.NET 4.5中状态机工作流

NET 4.5 中状态机工作流

结尾的总结有点与本文主题不符,是写文章时想到的,就顺手写上了(^_^)

例子下载:

http://files.cnblogs.com/foundation/Wxwinter.Test.Statements.rar

介绍

.NET 4.5 中WF已为原WF4.0提供了状态机模式的支持.

先看一下增加加的Activity

使用VS2011创建WorkFlow项目,选 .NET 4.5 的WF模板

尝试.NET 4.5中状态机工作流

在WF设计界面可以看到状态机模板

尝试.NET 4.5中状态机工作流

由3个Activity组成

StateMachin 是状态机容器

State 是状态节点

FinalState 是结束状态节点

尝试.NET 4.5中状态机工作流

在State 中具有[进入状态],[结束状态]两个执行区,可以添加任意Activity,

FinalState 中具有[进入状态]

State可以添加多条分支,在分支上可以设置[Trigger],[Condition],[Action],这些与WF4.0中其他条件类Activity设置一样

尝试.NET 4.5中状态机工作流

例子

用一个例子演示一下状态机的使用

流程业务模型

尝试.NET 4.5中状态机工作流

设计书签

publicsealedclassresultBookmark: NativeActivity  


{  


publicInArgumentbookmarkName { getset}  


protectedoverrideboolCanInduceIdle  


{  



get 



{ returntrue}  


}  


protectedoverridevoidExecute(NativeActivityContextcontext)  


{  


stringbookmark = context.GetValue(bookmarkName);  


context.CreateBookmark(bookmark, newBookmarkCallback(bookmarkCallback));  



System.Console.WriteLine("创建bookmark:{0}", bookmark);  



}  


voidbookmarkCallback(NativeActivityContextcontext, Bookmarkbookmark, objectobj)  


{  



if(obj != null)  



{  



this.Result.Set(context, obj.ToString());  



}  



else 



{  



this.Result.Set(context, string.Empty);  



}  


}  


} 

在设计界面用WF构建业务模型

尝试.NET 4.5中状态机工作流

设计State,以[A]节点为例,其他类似

尝试.NET 4.5中状态机工作流

尝试.NET 4.5中状态机工作流

设计宿主

尝试.NET 4.5中状态机工作流

voidworkflowCompleted(WorkflowApplicationCompletedEventArgse)  


{  



instance = null 




System.Console.WriteLine("workflowCompleted:{0}", e.CompletionState.ToString());  



}  


voidaborted(WorkflowApplicationAbortedEventArgse)  


{  



instance = null 




System.Console.WriteLine("aborted ,Reason:{0}", e.Reason.Message);  



}  


UnhandledExceptionActionunhandledExceptionl(WorkflowApplicationUnhandledExceptionEventArgse)  


{  



System.Console.WriteLine("unhandledException:{0}", e.UnhandledException.Message);  



returnUnhandledExceptionAction.Cancel;  


}  


voidworkflowIdel(WorkflowApplicationIdleEventArgse)  


{  



System.Console.WriteLine("Idle:{0}", e.InstanceId);  




System.Console.WriteLine("--------BookmarkName---------------------------");  




foreach(varitem ine.Bookmarks)  



{  



System.Console.WriteLine("{0}", item.BookmarkName);  



}  



System.Console.WriteLine("================================");  



}  



WorkflowApplicationinstance = null 



privatevoidstartButton_Click(objectsender, EventArgse)  


{  


valueComboBox.Items.Clear();  



valueComboBox.Items.Add("A");  




valueComboBox.Items.Add("B");  




valueComboBox.Items.Add("C");  




valueComboBox.Items.Add("E");  




valueComboBox.SelectedItem = "B" 



instance = newWorkflowApplication(newmyWorkflow());  


instance.Completed = newAction(workflowCompleted);  


instance.OnUnhandledException = unhandledExceptionl;  


instance.Aborted = aborted;  


instance.Idle = workflowIdel;  


instance.Run();  


}  


privatevoidsubmitButton_Click(objectsender, EventArgse)  


{  


stringbookName =bookmarkTextBox.Text;  


stringinputValue = valueComboBox.SelectedItem.ToString();  



if(instance != null)  



{  



if(instance.GetBookmarks().Count(p => p.BookmarkName == bookName) == 1)  



{  


instance.ResumeBookmark(bookName, inputValue);  


}  



else 



{  



foreach(varv ininstance.GetBookmarks())  



 {  



System.Console.WriteLine("--------请从下面选项中选择一个BookmarkName---------------------------");  




System.Console.WriteLine("BookmarkName:{0}:,OwnerDisplayName:{1}", v.BookmarkName, v.OwnerDisplayName);  




System.Console.WriteLine("================================");  



}  


}  


}  



else 



{  



MessageBox.Show("没有创建实例");  



}  


} 

测试

尝试.NET 4.5中状态机工作流

尝试.NET 4.5中状态机工作流

总结

这本是一个应在NET 4.0 中实现的功能,其实不谈数据结构与运行机制,FlowChar完全可以实现StateMachin 的所有业务逻辑.

只不过StateMachin 在VS设计器中给人一种更整洁的感觉,不过这只是展现层面的东西,之前不少人都实现过这种效果(包括我自已),理论上并不是很难,但由于WF4.0大部分的功能类从继承Object后就开始封闭与工程级保护,在这种情况下别说继承,就正常连引用都办不到,当然也有办法解决,不过实现后一般只做为概念展现,所以很多人在实际使用时采取的是自定义流程设计器,将FlowChar的结构展现成StateMachin ,通过拦截Bookmark实现[进入状态],[结束状态],其实这种工作量比传统意义上开发一套业务流程平台还有大,但为什么还有使用WF,这是很多人不理解的.其实使用WF的人基本分为两类,一类是具备设计器开发能力的人,看到VS中的WF设计界面后就觉得WF为其提供了一套拿来就能用的业务流程平台.这种想法是不对的,暂不分析WF是否只接适用用户业务,就常识来说,与WCF,WPF并列的WF怎么可能是直接面对业务用户的.另一类选择WF的人是看中了WF对状态的副本处理,事物处理,补偿处理这些从COM+延续下来的理念.很多时候我一直认为WCF +WF就是一个新版本的COM+

最后不得不提一下,虽然WF实现了FlowChar与StateMachin ,但其数据结构并不是图,而是树.如果既对Expression Tree熟悉,又对WF熟悉,你会发现Expression Tree就是一个WF数据结构精简版.谈到Expression Tree了解的人是多了,我也好解释了,这种数结构其实与内存中的栈管理方式很象,这就决定了调用只能指向栈开始,而不能任意指向栈的任意位置(不谈溢出,GOTO指针这个层面的问题).

为什么提上面这段内容,是因为我要说明由于这种数据结构我们很难现以下功能(这是一个业务功能,我先用C#风格有代码描述一下):

尝试.NET 4.5中状态机工作流

上面这段代码看起来有些疯狂,我们不从代码层面考虑(不加条件判断,不提动态编译,ICO,AOP),我只想这样写,我希望当程序运行到[24]时自动告诉我缺少哪个上下文(如obj),并让我补齐上下文后继续执行.

将这个问题业务化:

上车前要买票,(买票是上车的前置条件)

但我已经上了车却没买票,是补票还是将我赶下车买完票再上车.这就是经典的[补偿处理]机制

程序员说:"你们的业务总变,你们都说不清,让我们怎么开发"

客户说:"我们要是业务从来不变,每个人都能说清,要你们开发系统做什么"

相关推荐