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

相关文章

Knife4j+Axios+Redis前后端分离架构下的 API 管理与会话方案(最新推荐)

《Knife4j+Axios+Redis前后端分离架构下的API管理与会话方案(最新推荐)》本文主要介绍了Swagger与Knife4j的配置要点、前后端对接方法以及分布式Session实现原理,... 目录一、Swagger 与 Knife4j 的深度理解及配置要点Knife4j 配置关键要点1.Spri

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

mysql中的服务器架构详解

《mysql中的服务器架构详解》:本文主要介绍mysql中的服务器架构,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、mysql服务器架构解释3、总结1、背景简单理解一下mysqphpl的服务器架构。2、mysjsql服务器架构解释mysql的架

k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)

《k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)》本文记录在K8s上运行的MySQL/MariaDB备份方案,通过工具容器执行mysqldump,结合定时任务实... 目录前言一、获取需要备份的数据库的信息二、备份步骤1.准备工作(X86)1.准备工作(arm)2.手

Java中JSON格式反序列化为Map且保证存取顺序一致的问题

《Java中JSON格式反序列化为Map且保证存取顺序一致的问题》:本文主要介绍Java中JSON格式反序列化为Map且保证存取顺序一致的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未... 目录背景问题解决方法总结背景做项目涉及两个微服务之间传数据时,需要提供方将Map类型的数据序列化为co

RedisTemplate默认序列化方式显示中文乱码的解决

《RedisTemplate默认序列化方式显示中文乱码的解决》本文主要介绍了SpringDataRedis默认使用JdkSerializationRedisSerializer导致数据乱码,文中通过示... 目录1. 问题原因2. 解决方案3. 配置类示例4. 配置说明5. 使用示例6. 验证存储结果7.

SpringBoot实现Kafka动态反序列化的完整代码

《SpringBoot实现Kafka动态反序列化的完整代码》在分布式系统中,Kafka作为高吞吐量的消息队列,常常需要处理来自不同主题(Topic)的异构数据,不同的业务场景可能要求对同一消费者组内的... 目录引言一、问题背景1.1 动态反序列化的需求1.2 常见问题二、动态反序列化的核心方案2.1 ht

SpringBoot项目中Redis存储Session对象序列化处理

《SpringBoot项目中Redis存储Session对象序列化处理》在SpringBoot项目中使用Redis存储Session时,对象的序列化和反序列化是关键步骤,下面我们就来讲讲如何在Spri... 目录一、为什么需要序列化处理二、Spring Boot 集成 Redis 存储 Session2.1

Maven 插件配置分层架构深度解析

《Maven插件配置分层架构深度解析》:本文主要介绍Maven插件配置分层架构深度解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Maven 插件配置分层架构深度解析引言:当构建逻辑遇上复杂配置第一章 Maven插件配置的三重境界1.1 插件配置的拓扑

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四