1.首先,项目的目标框架要选择.Net4.5版本,才有状态机工作流。
2.新建“活动”项,先从工具栏拖出一个StateMachine,然后添加其他状态,通过调整状态间的连线,使两状态成为上一状态和下一状态的关系,每种状态都要有一个终态。
下面会有代码介绍如何新建一个工作流。
1.定位到 C:\Windows\Microsoft.NET\Framework\v4.0.30319\SQL\en 文件夹,需要用到 SqlWorkflowInstanceStoreSchema.sql 和 SqlWorkflowInstanceStoreLogic.sql 这两个sql文件。
2.打开需要加入工作流持久化的数据库,右击该数据库,选择新建查询,先后执行两个脚本,则看到数据库中多了几张表(如下图)
3.创建一个空闲时自动实例化的工作流
1 //如果你想要使用工作流进行序列化和持久化。
2 WorkflowApplication application = new WorkflowApplication(new TestActivity());
3
4
5
6 SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore(conStr);
7 //让当前的我们的applicaton实例跟 数据库关联一块
8 application.InstanceStore = store;
9
10 //当工作流空闲的时候立即让我们工作流进行卸载,之前先序列化到 咱们的 数据库里面去。
11
12 application.PersistableIdle = arg => { return PersistableIdleAction.Unload; };
13 //当工作流被卸载时显示卸载信息
14 application.Unloaded += a => { Console.WriteLine("工作流停下来了"); };
15 application.Run();//启动一个新的线程帮助我们执行工作流。
1.新建一个winform项目,更改项目输出类型为“控制台”。
2.新建“代码活动”项,修改新建项的代码如下:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Activities;
6
7 namespace TestWF
8 {
9 //书签有4步
10 //1.改基类:CodeActivity改为NativeActivity
11 //2.重写属性CanInduceIdle,改为return true;
12 //3.修改Execute方法的传入参数类型CodeActivityContext改为NativeActivityContext
13 //4.利用context.CreateBookmark(text,new BookmarkCallback(MyCallBack));创建书签
14 public sealed class BookMarkActivity : NativeActivity
15 {
16 // 定义一个字符串类型的活动输入参数
17 public InArgument<string> Text { get; set; }
18
19 protected override bool CanInduceIdle
20 {
21 get
22 {
23 return true;
24 }
25 }
26
27
28 // 如果活动返回值,则从 CodeActivity<TResult>
29 // 派生并从 Execute 方法返回该值。
30 protected override void Execute(NativeActivityContext context)
31 {
32 // 获取 Text 输入参数的运行时值
33 //string text = context.GetValue(this.Text);
34
35 context.CreateBookmark("TestWF",MyCallBack);
36 }
37
38 private void MyCallBack(NativeActivityContext context, Bookmark bookmark, object value)
39 {
40 //可以在书签中操作书签的返回值
41 }
42 }
43 }
3.新建“活动”项,拖出工作流如下图所示:
在审查金额状态中,添加如下项(如果工具栏中不存在BookMark项,请重新生成解决方案试试):
4.在项目中添加app.config配置文件,添加连接字符串的appSetting项:
1 <?xml version="1.0" encoding="utf-8" ?>
2 <configuration>
3 <startup>
4 <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
5 </startup>
6 <appSettings>
7 <add key="conStr" value="Data Source=./;Initial Catalog=MyOA;Integrated Security=true; "/>
8 </appSettings>
9 </configuration>
5.Form1窗口的设计:
6.在Form1.cs中添加代码:
1 using System;
2 using System.Activities;
3 using System.Activities.DurableInstancing;
4 using System.Collections.Generic;
5 using System.ComponentModel;
6 using System.Configuration;
7 using System.Data;
8 using System.Drawing;
9 using System.Linq;
10 using System.Text;
11 using System.Threading.Tasks;
12 using System.Windows.Forms;
13
14 namespace TestWF
15 {
16
17 public partial class Form1 : Form
18 {
19 public Form1()
20 {
21 InitializeComponent();
22 textBox1.Text = Clipboard.GetText();
23 }
24
25 public static string conStr = ConfigurationManager.AppSettings["conStr"];
26 private void button3_Click(object sender, EventArgs e)
27 {
28 #region 开启工作流代码
29 //如果你想要使用工作流进行序列化和持久化。
30 WorkflowApplication application = new WorkflowApplication(new TestActivity());
31
32
33
34 SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore(conStr);
35 //让当前的我们的applicaton实例跟 数据库关联一块
36 application.InstanceStore = store;
37
38 //当工作流空闲的时候立即让我们工作流进行卸载,之前先序列化到 咱们的 数据库里面去。
39
40 application.PersistableIdle = arg => { return PersistableIdleAction.Unload; };
41 //当工作流被卸载时显示卸载信息
42 application.Unloaded += a => { Console.WriteLine("工作流停下来了"); };
43 application.Run();//启动一个新的线程帮助我们执行工作流。
44 #endregion
45 textBox1.Text = application.Id.ToString();
46 //将工作流的guid粘贴到剪贴板中,以便下一次程序启动时能取到
47 Clipboard.SetText(textBox1.Text);
48
49 }
50
51 private void button2_Click(object sender, EventArgs e)
52 {
53 #region 恢复工作流代码
54 WorkflowApplication application = new WorkflowApplication(new TestActivity());
55
56 SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore(conStr);
57 //让当前的我们的applicaton实例跟 数据库关联一块
58 application.InstanceStore = store;
59
60 //当工作流空闲的时候立即让我们工作流进行卸载,之前先序列化到 咱们的 数据库里面去。
61 application.PersistableIdle = arg => { return PersistableIdleAction.Unload; };
62
63 application.Load(Guid.Parse(textBox1.Text));
64 application.ResumeBookmark("TestWF","");
65 #endregion
66 }
67
68
69 }
70 }
7.运行结果如下图:
当点击“开启工作流”时,提示“请输入金额”,当输入金额回车后由于有书签,工作流停下来被实例化到数据库中程序打印出“工作流停下来了”,再点击“重新开启工作流”,工作流继续运行到其他FinalState状态。