VS2005+WWF开发入门实例
在VS2005中先安装WWF。
一、最简单的工作流DEMO_工作台顺序工作流
在VS2005中新建一个WorkFlow工作流项目:WorkflowConsoleApplication1.sln,如图:
添加一个CodeActivity,界面效果如下:
双击CodeActivity,在后台添加如下代码:
OK,最简单的一个工作流就完成了。
点击运行按钮,效果如下:
。
二、Windows程序调用工作流。并把参数传递到工作流中。
(1)工作流的开发:控制台顺序工作流:
}注意要添加引用:using System.Windows.Forms;
(2)WIndows程序的开发:
窗口中有两个Textbox,用于输入参数,参数传递到工作流中,并在工作流程序的MessageBox中显示出来。
将Windows设置为启动项目。运行即可。
三、工作流SqlTrackingService使用实例。(工作流的跟踪)
SqlTrackingService用于跟踪工作流的运行情况。就是将工作流的运行情况保存到数据库中,以便用户查看工作流在某个时间的执行情况,微软提供了建立跟踪信息的表建表脚本。该脚本一般情况下位于C:/WINDOWS/Microsoft.NET/Framework/v3.0/Windows Workflow Foundation/SQL/EN。
1、新建工作流:
设置界面只有一个CodeActivity:
后台代码:
using System; using System.ComponentModel; using System.ComponentModel.Design; using System.Collections; using System.Drawing; using System.Workflow.ComponentModel.Compiler; using System.Workflow.ComponentModel.Serialization; using System.Workflow.ComponentModel; using System.Workflow.ComponentModel.Design; using System.Workflow.Runtime; using System.Workflow.Activities; using System.Workflow.Activities.Rules;
namespace SQLTrackingDEMO { public sealed partial class Workflow1: SequentialWorkflowActivity { public Workflow1() { InitializeComponent(); }
private void codeActivity1_ExecuteCode(object sender, EventArgs e) { Console.WriteLine("Hello eNet!!!"); } }
}
Program.cs文件:
#region Using directives
using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Workflow.Runtime; using System.Workflow.Runtime.Hosting; using System.Workflow.Runtime.Tracking;
#endregion
namespace SQLTrackingDEMO { class Program { static string connectionString = @"Data Source=F4C09CAB317E46C/SQLEXPRESS;Initial Catalog=SqlTrackDB;Integrated Security=True;";
static void Main(string[] args) { using(WorkflowRuntime workflowRuntime = new WorkflowRuntime()) { SqlTrackingService MytrackingServer = new SqlTrackingService(connectionString);
workflowRuntime.AddService(MytrackingServer);
AutoResetEvent waitHandle = new AutoResetEvent(false);
workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) { waitHandle.Set(); };
workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e) {
Console.WriteLine(e.Exception.Message);
waitHandle.Set();
};
WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(SQLTrackingDEMO.Workflow1));
instance.Start();
instance.Suspend("Reason we are suspending the workflow.");
instance.Resume();
waitHandle.WaitOne();
// 取得Insance的运行情况
GetInstanceTrackingEvents(instance.InstanceId); GetInstanceTrackingEvents(instance.InstanceId);
Console.WriteLine("工作流结束。");
Console.Read();
} }
static void GetInstanceTrackingEvents(Guid instanceId) {
Console.WriteLine("/r/n开始Instance 跟踪事件:");
SqlTrackingQuery MysqlTrackingQuery = new SqlTrackingQuery(connectionString);
SqlTrackingWorkflowInstance MysqlTrackingWorkflowInstance;
MysqlTrackingQuery.TryGetWorkflow(instanceId, out MysqlTrackingWorkflowInstance);
try {
foreach (WorkflowTrackingRecord workflowTrackingRecord in MysqlTrackingWorkflowInstance.WorkflowEvents) {
Console.WriteLine("事件描述 :{0} 时间: {1}",
workflowTrackingRecord.TrackingWorkflowEvent, workflowTrackingRecord.EventDateTime);
}
}
catch (Exception) {
Console.WriteLine("没有发现Instance Tracking Events");
}
}
} }
运行效果:
下面是Windows程序启动工作流并进行跟踪的程序:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms;
using System.Threading; using System.Workflow.Runtime; using System.Workflow.Runtime.Hosting; using System.Workflow.Runtime.Tracking;
namespace SqlTracking { public partial class Form1 : Form { public Form1() { InitializeComponent(); }
private void Form1_Load(object sender, EventArgs e) {
} static string connectionString = @"Data Source=F4C09CAB317E46C/SQLEXPRESS;Initial Catalog=SqlTrackDB;Integrated Security=True;";
private void button1_Click(object sender, EventArgs e) {
using (WorkflowRuntime workflowRuntime = new WorkflowRuntime()) { SqlTrackingService MytrackingServer = new SqlTrackingService(connectionString);
workflowRuntime.AddService(MytrackingServer);
AutoResetEvent waitHandle = new AutoResetEvent(false);
workflowRuntime.WorkflowCompleted += delegate(object sender1, WorkflowCompletedEventArgs ee) { waitHandle.Set(); };
workflowRuntime.WorkflowTerminated += delegate(object sender1, WorkflowTerminatedEventArgs ee) {
this.textBox1.AppendText(ee.Exception.Message); Console.WriteLine(ee.Exception.Message);
waitHandle.Set();
};
WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(SqlTracking.Workflow1));
instance.Start();
instance.Suspend("Reason we are suspending the workflow.");
instance.Resume();
waitHandle.WaitOne();
// 取得Insance的运行情况
GetInstanceTrackingEvents(instance.InstanceId); //GetInstanceTrackingEvents(instance.InstanceId); this.textBox1.AppendText("/r/n工作流结束。"); // Console.WriteLine("工作流结束。");
//Console.Read();
} }
private void GetInstanceTrackingEvents(Guid instanceId) {
// Console.WriteLine("/r/n开始Instance 跟踪事件:");
textBox1.AppendText("/r/n开始Instance 跟踪事件:");
SqlTrackingQuery MysqlTrackingQuery = new SqlTrackingQuery(connectionString);
SqlTrackingWorkflowInstance MysqlTrackingWorkflowInstance;
MysqlTrackingQuery.TryGetWorkflow(instanceId, out MysqlTrackingWorkflowInstance);
try {
foreach (WorkflowTrackingRecord workflowTrackingRecord in MysqlTrackingWorkflowInstance.WorkflowEvents) { textBox1.AppendText("/r/n事件描述 :" + workflowTrackingRecord.TrackingWorkflowEvent + " ,时间:" + workflowTrackingRecord.EventDateTime);
}
}
catch (Exception) { textBox1.AppendText("/r/n没有发现Instance Tracking Events"); // Console.WriteLine("没有发现Instance Tracking Events");
}
} } }
四、ifElse库(Activity)的使用实例(通过属性将数据传递到WF内部)
关于IfElse的Activity库的条件,有两种设置方式,“声明性规则条件”和“代码”
此处采用,“声明性规则条件”,就是直接在WWF的IfElse控件中书写条件。界面如下:
WorkflowLibrary1.cs文件源码:
using System; using System.ComponentModel; using System.ComponentModel.Design; using System.Collections; using System.Drawing; using System.Workflow.ComponentModel.Compiler; using System.Workflow.ComponentModel.Serialization; using System.Workflow.ComponentModel; using System.Workflow.ComponentModel.Design; using System.Workflow.Runtime; using System.Workflow.Activities; using System.Workflow.Activities.Rules;
namespace WorkflowLibrary1 { public sealed partial class Workflow1: SequentialWorkflowActivity { public Workflow1() { InitializeComponent(); } private string _innum; public string INNUM { set { _innum = value; } get { return _innum; } }
private void codeActivity1_ExecuteCode(object sender, EventArgs e) { Console.WriteLine("你输入的值是:"+this._innum);
}
private void codeActivity2_ExecuteCode(object sender, EventArgs e) { Console.WriteLine("你输入的值大于1000,该由总经理审批"); }
private void codeActivity3_ExecuteCode(object sender, EventArgs e) { Console.WriteLine("你输入的值ih 于1000,该由项目经理审批就行了。"); }
}
}
调用WWF的主程序代码(WinForm程序)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime; using System.Workflow; using System.Workflow.Activities; using System.Workflow.Runtime;
using System.Threading;
namespace WindowsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private WorkflowRuntime wr; private void button1_Click(object sender, EventArgs e) {
if (wr == null) {
wr = new WorkflowRuntime();
wr.StartRuntime(); }
Dictionary<string, object> parameters = new Dictionary<string, object>(); parameters.Add("INNUM", this.textBox1.Text); WorkflowInstance instance = wr.CreateWorkflow(typeof(WorkflowLibrary1.Workflow1), parameters); instance.Start();//启动工作流
Console.Read();
} } }
运行后,根据输入的数据不同,传递到WWF内部,在控制台中输出不同的数据。
五、工作流中调用外部方法实例。(徐栋的Windows Workflow Foundation开发实战系列课程(3):流程通讯开发源码)
我从网上到处都找不到这个代码,就自己按教程弄出来了。下载地址:
http://download.csdn.net/source/503950 徐栋 Windows Workflow Foundation开发实战系列课程(3):流程通讯开发源码
1、VotingService.cs文件:
using System; using System.Collections.Generic; using System.Text; using System.Workflow.Activities; using System.Windows.Forms;
namespace WorkflowConsoleApplication2 { /// <summary> /// 定义工作流服务接口 /// </summary> [System.Workflow.Activities.ExternalDataExchange] internal interface IVotingServices//定义接口 { //定义两个事件,一个同意一个拒绝, event EventHandler<VotingServiceEventArgs> ApprovedProposal; event EventHandler<VotingServiceEventArgs> RejectProposal; //定义一个方法 void CreateBallot(string alias);
} /// <summary> /// 定义工作流服务事件参数
/// </summary> [Serializable] internal class VotingServiceEventArgs : ExternalDataEventArgs {
private string aliasvalue;
public VotingServiceEventArgs(Guid instanceID, string alias)//构造函数,从宿主程序传递alias到此 : base(instanceID) { this.aliasvalue = alias; }
public string Alias { get { return this.aliasvalue; } }
} /// <summary> /// 定义工作流服务实现类 /// </summary>
internal class VotingServiceImpl : IVotingServices { public event EventHandler<VotingServiceEventArgs> ApprovedProposal; public event EventHandler<VotingServiceEventArgs> RejectProposal;
public void CreateBallot(string alias) { Console.WriteLine("Bollot created for {0}.", alias); ShowVotingDialog(new VotingServiceEventArgs(System.Workflow.Runtime.WorkflowEnvironment.WorkflowInstanceId,alias)); }
public void ShowVotingDialog(VotingServiceEventArgs votingEventArgs) { DialogResult result; string alias = votingEventArgs.Alias;
result = MessageBox.Show(string.Format("Approved Proposal,{0}?",alias),string.Format("{0} Bollot",alias),MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { EventHandler<VotingServiceEventArgs> approvedProposal = this.ApprovedProposal; if (approvedProposal != null) approvedProposal(null, votingEventArgs); } else { EventHandler<VotingServiceEventArgs> rejectProposal = this.RejectProposal; if (rejectProposal != null) rejectProposal(null, votingEventArgs); } } }
}
2、工作流设计:
使用callExternalMethodActivity调用外部方法:
使用listenActivity监听外部的事件。
使用handleExternalEventActivity调用外部的事件。
总体设计效果如下:
callExternalMethodActivity的属性:(注意调用的方法中有一个参数,别忘了设置)如下:
ListenActivity的属性不需要设置。
handleExternalEventActivity1的属性:
运行效果:
源码下载:http://download.csdn.net/user/xjzdr/
六、WWF中调用外部方法的简单DEMO
1、IWWFDEMO.cs文件:
using System; using System.Collections.Generic; using System.Text; using System.Workflow.Activities;
namespace WorkflowLibrary4 { /// <summary> /// 定义工作流服务接口 /// </summary> [System.Workflow.Activities.ExternalDataExchange] public interface IWWFDEMO//定义接口 {
//定义两个方法,其中一个有参数,一个没有参数 void CreateBallot1();//调用程序输入的将QQ号通过外部方法传入工作流中,并在工作流中打印出来 void CreateBallot2(string StrQQ); } /// <summary> /// 实现类 /// </summary> public class WWFDEMO : IWWFDEMO { public void CreateBallot1() { Console.WriteLine("Bollot created for"); } public void CreateBallot2(string myqq) { System.Windows.Forms.MessageBox.Show("你输入的值是"+myqq); }
} }
2、wwf设计
CODEActivity执行代码:
private void codeActivity1_ExecuteCode(object sender, EventArgs e) { Console.WriteLine(this.StrQQ1.ToString()); }
运行结果:
说明:对于只调用外部方法,并不需要传递参数的时候,不需要进行可化类的开发。