WF随笔系列之二:架构、编译、序列化

2024-04-17 01:18

本文主要是介绍WF随笔系列之二:架构、编译、序列化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

来源:BrianLei Blog - 博客园
  WF随笔系列之二,我们谈三个话题
  1.Windows Workflow Foundation架构图
-----Workflow与host交互的例子
  2.Windows Workflow Foundation的编译
  3.Windows Workflow Foundation Serialization话题
------如何序列化Workflow和以及反序列化
 2.1 Windows Workflow Foundation架构图:

  补充,运行时引擎:

  其实,在完成、失败和空闲的几种工作流实例的状态下,工作流运行时引擎应该表现出几种不同的事件。
如:

WorkflowAborted
WorkflowCompleted
WorkflowCreated
  事实上,workflow不是孤立运行的。因为WF在一个工作流实例和它的host之间提供了一些机制可以相互通信。那在工作流的内部或者外部,也提供很多的通讯方法能够让你快速和容易的传递数据,同时在一个工作流的环境外部,也有许多的可定制的方法能够支持你处理额外的事件和调用。

  2.2 Workflow与host交互的例子
首先,创建SequentialConsoleApplication工程,然后在Workflow1.cs[Design]拖一个Code,双击codeActivity1,在后台代码中,建立三个私有字段
private int A,B,C;
public int C { get { return OutputResult; } }
public int B { set { B = value; } }
public int A { set { A = value; } }
在ExecuteCode方法
private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
C = A + B;
Console.WriteLine("At First,ExecuteCodeActivity1");
}

  在Program.cs Main方法中
  1. 声明一个 Dictionary
  2. 针对以上codeActivtiy1.cs建立字段,添加A,B元素的Value
Dictionary parameters = new Dictionary();

parameters["A"] = 11;
parameters["B"] = 22;
  3. 完成CreateWorkflow,以及WorkflowCompleted事件
WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(CFirstSequentialWFConsoleApplication.Workflow1), parameters);

instance.Start();

workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) { Console.WriteLine(e.OutputParameters["C"]); };

  至此,Workflow与host的Communication就完成。
当你在Host 应用程序中启动Workflow时,会直接调用WorkflowRuntime类中的CreateWorkflow方法,然后通过Dictionary实例把需要操作的数据传输到Workflow中进行相应处理,最后在WorkflowCompleted事件中获得操作之后的结果。

  2.3 Windows Workflow Foundation的编译
  在.net程序集中编译工作流,一般是这样顺序
  首先,workflow 编译,在这其中会包括Activity 验正,Activity代码的生成
  然后, 经过语言编译(这里的语言指的C#,VB.net等等),最后形成.net程序集。
  那编译完成之后,如何进行调用,其次就是实例化一个Runtime即可,然后调用startRuntime(),就OK了。

  2.4 Windows Workflow Foundation Serialization话题
WWF FrameWork提供序列化的机制,workflow和activity都是可以进行序列化和反序列化。另外RuleConditions and RuleSets 也是可以序列化成 .rules 文件关联Workflow.

  序列化类
System.Workflow.ComponentModel.Serialization
在Serialization命名空间下有三个Serializer:

WorkflowMarkupSerializer
  此类是Windows Workflow Foundation 所有序列化类的基类。你能使用其对workflows和activities进行序列化,序列化成xoml文件。当然,你也能把xoml文件反序列化成workflows和activites.
ActivityMarkupSerializer
针对于Activity序列化
CompositeActivityMarkupSerializer
针对于CompositeActivity序列化
当然也可以自定义序列化,如何自定义序列化?

  直接在你要序列化类上面,加一个属性,然后在进行相应的Coding。
举例如下:

[DesignerSerializer(typeof(CustomSerializer),typeof(WorkflowMarkupSerializer))]
public class workflow
{

.//Coding

}

  以上属性中第一参数是需要序列化的类,第二参数是代表第一个参数的基类型。    2.5 如何序列化Workflow和以及反序列化
首先建立一个WorkflowActivityLibrary项目
然后Activity1属性中,Base Class选择System.Workflow.ComponentModel.Activity
再建立一个WorkflowConsoleApplication项目
最后在Main方法直接Coding,代码如下
using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{
AutoResetEvent waitHandle = new AutoResetEvent(false);
workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e)
{
Console.WriteLine("Workflow completed.");
waitHandle.Set();
};

 //创建Workflow
 Console.WriteLine("Creating workflow.");
 SequentialWorkflowActivity workflow = new SequentialWorkflowActivity();
 workflow.Name = "created workflow";
 workflow.Description = "created workflow for XOML activation";
 Activity activity = new Activity();
 activity.Name = "ConsoleActivity1";
 workflow.Activities.Add(activity); .
}
  序列化workflow到Xoml
WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
using (XmlWriter writer = XmlWriter.Create(workflowFilename))
{
 DesignerSerializationManager serializationManager = new DesignerSerializationManager();
/**CreateSession()创建新序列化会话。
 using (serializationManager.CreateSession())
 {
 serializer.Serialize(serializationManager, writer, workflow);
 //当然要检查在序列化中发生错误时,就可以给于相应的提示信息或者记录日志什么的,
 //那在DesignerSerializationManager类中有一个公共属性Errors,
 //公共属性Errors是获取在序列化或反序列化期间发生的错误的列表。
 if (serializationManager.Errors.Count > 0)
 {
 Console.WriteLine(String.Format("序列化时出错!{0}", serializationManager.Errors.Count));
 return;
 }
 }
 }
反序列化文件到workflow

//创建Workflow实例
 WorkflowInstance deserializedWorkflow = null;
 try
 {
 using (XmlReader reader = XmlReader.Create(workflowFilename))
 {
 deserializedWorkflow = workflowRuntime.CreateWorkflow(reader);
 }
 }
 catch (WorkflowValidationFailedException exp)
 {
  return;
 }
序列化之后,会生成一个.Xoml 文件,以下是内容


x:Name="created workflow"
Description="created workflow for XAML activation" xmlns:ns0="clr-namespace:Microsoft.Samples.Workflow.WorkflowSerialization; Assembly=CustomActivity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">


  其实大家看一下序列化之后的Xoml文件,可发现
  1.在XOML中对象类型是为xml节点名 如:x:Name,Description
  2.在XOML中对象属性值是xml节点的属性值 如:created workflow
  3.在XOML中还包括 ,这个就是我们在上面添加的子Activity.
  其实,有关于序列化还是有许多可讲的,我在以后会进行穿插的。

CreateSession()补充:
序列化管理器中的大多数数据都是瞬态的,只在序列化会话期间存活。
当释放某个会话时,会认为序列化已经完成,并且会清除该瞬态。
这允许使用序列化管理器的一个实例序列化多个对象树。
有的状态(包括服务提供程序和添加到序列化管理器的任何自定义的序列化提供程序)是跨会话的。

  引文:
  DesignerSerializationManager 类基于序列化会话这一理念。
  会话维护可由各种序列化程序访问的状态。当释放会话时,该状态会损坏。
  这有助于确保序列化程序主要保持无状态,并且有助于清理已经损坏的序列化程序。

  DesignerSerializationManager 类可实现三个目标:
  它是一个简单的总控对象,可以用来对各种格式进行反序列化。
  它是通用的,不绑定到任何特定格式。对于 CodeDOM 反序列化以及标记反序列化,它的使用方式相同。

  它是可扩展的,并且支持在复制/粘贴和撤消/重复方案中使用的不同序列化方法。
设计时序列化与运行时对象序列化具有下列不同之处:
  执行序列化的对象通常与运行时对象是分离的,因此,可从组件中移除设计时逻辑。
  序列化方案假定将要创建完全初始化的对象,然后在反序列化期间通过属性和方法调用对其进行修改。

  如果对象的属性具有从未在该对象上设置过的值(这些属性包含默认值),就不会对这些属性进行序列化。相反,反序列化流可能会有漏洞。
  重点是序列化流中的内容的质量,而不是对象的完全序列化。
  这表示,如果没有定义序列化对象的方法,则可以跳过该对象,否则会引发异常。
  序列化引擎可以在这里提供试探法来确定可以忽略哪些失败以及哪些失败不可恢复。
  序列化流具有的数据可能多于反序列化所需的数据。
例如,源代码序列化已将用户代码与反序列化对象图所需的代码混合。
  对于反序列化,必须忽略该用户代码,而对于序列化,必须保留该用户代码。

这篇关于WF随笔系列之二:架构、编译、序列化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/910418

相关文章

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

Java异常架构Exception(异常)详解

《Java异常架构Exception(异常)详解》:本文主要介绍Java异常架构Exception(异常),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. Exception 类的概述Exception的分类2. 受检异常(Checked Exception)

Django序列化中SerializerMethodField的使用详解

《Django序列化中SerializerMethodField的使用详解》:本文主要介绍Django序列化中SerializerMethodField的使用,具有很好的参考价值,希望对大家有所帮... 目录SerializerMethodField的基本概念使用SerializerMethodField的

Jackson库进行JSON 序列化时遇到了无限递归(Infinite Recursion)的问题及解决方案

《Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursion)的问题及解决方案》使用Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursi... 目录解决方案‌1. 使用 @jsonIgnore 忽略一个方向的引用2. 使用 @JsonManagedR

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

MySQL 缓存机制与架构解析(最新推荐)

《MySQL缓存机制与架构解析(最新推荐)》本文详细介绍了MySQL的缓存机制和整体架构,包括一级缓存(InnoDBBufferPool)和二级缓存(QueryCache),文章还探讨了SQL... 目录一、mysql缓存机制概述二、MySQL整体架构三、SQL查询执行全流程四、MySQL 8.0为何移除查

微服务架构之使用RabbitMQ进行异步处理方式

《微服务架构之使用RabbitMQ进行异步处理方式》本文介绍了RabbitMQ的基本概念、异步调用处理逻辑、RabbitMQ的基本使用方法以及在SpringBoot项目中使用RabbitMQ解决高并发... 目录一.什么是RabbitMQ?二.异步调用处理逻辑:三.RabbitMQ的基本使用1.安装2.架构

解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题

《解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题》文章详细描述了在使用lombok的@Data注解标注实体类时遇到编译无误但运行时报错的问题,分析... 目录问题分析问题解决方案步骤一步骤二步骤三总结问题使用lombok注解@Data标注实体类,编译时

Java中JSON字符串反序列化(动态泛型)

《Java中JSON字符串反序列化(动态泛型)》文章讨论了在定时任务中使用反射调用目标对象时处理动态参数的问题,通过将方法参数存储为JSON字符串并进行反序列化,可以实现动态调用,然而,这种方式容易导... 需求:定时任务扫描,反射调用目标对象,但是,方法的传参不是固定的。方案一:将方法参数存成jsON字

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin