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整合Protocol Buffers实现高效数据序列化实践

《Java整合ProtocolBuffers实现高效数据序列化实践》ProtocolBuffers是Google开发的一种语言中立、平台中立、可扩展的结构化数据序列化机制,类似于XML但更小、更快... 目录一、Protocol Buffers简介1.1 什么是Protocol Buffers1.2 Pro

Linux中的自定义协议+序列反序列化用法

《Linux中的自定义协议+序列反序列化用法》文章探讨网络程序在应用层的实现,涉及TCP协议的数据传输机制、结构化数据的序列化与反序列化方法,以及通过JSON和自定义协议构建网络计算器的思路,强调分层... 目录一,再次理解协议二,序列化和反序列化三,实现网络计算器3.1 日志文件3.2Socket.hpp

Go语言编译环境设置教程

《Go语言编译环境设置教程》Go语言支持高并发(goroutine)、自动垃圾回收,编译为跨平台二进制文件,云原生兼容且社区活跃,开发便捷,内置测试与vet工具辅助检测错误,依赖模块化管理,提升开发效... 目录Go语言优势下载 Go  配置编译环境配置 GOPROXYIDE 设置(VS Code)一些基本

Olingo分析和实践之EDM 辅助序列化器详解(最佳实践)

《Olingo分析和实践之EDM辅助序列化器详解(最佳实践)》EDM辅助序列化器是ApacheOlingoOData框架中无需完整EDM模型的智能序列化工具,通过运行时类型推断实现灵活数据转换,适用... 目录概念与定义什么是 EDM 辅助序列化器?核心概念设计目标核心特点1. EDM 信息可选2. 智能类

SpringSecurity整合redission序列化问题小结(最新整理)

《SpringSecurity整合redission序列化问题小结(最新整理)》文章详解SpringSecurity整合Redisson时的序列化问题,指出需排除官方Jackson依赖,通过自定义反序... 目录1. 前言2. Redission配置2.1 RedissonProperties2.2 Red

java使用protobuf-maven-plugin的插件编译proto文件详解

《java使用protobuf-maven-plugin的插件编译proto文件详解》:本文主要介绍java使用protobuf-maven-plugin的插件编译proto文件,具有很好的参考价... 目录protobuf文件作为数据传输和存储的协议主要介绍在Java使用maven编译proto文件的插件

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.手