开张那天就被Teddy's Knowledge Base与TerryLee 两位说没条理,不认真,
看了两位的家,真的不错,其实我没搬家前了不错,(是朋友帮整理的(^_^))
从小条理性就不强,上学时写作文总跑题,现在写文章也喜欢乱侃,这不,说"用WF开发大富翁..."又被ccBoy笑话了。还好,各位老大没看见我超级恶搞的技术文章,否则.......各位老大一定吐血
有些懒,不准备写[自定义Tracking],想打个哈哈就过去,没想到让ccBoy揭穿了,看人家的留言都比我的内容多,真不好意思。
用ccBoy为开头,将[自定义Tracking]补上吧
--------------------Begin 引用(ccBoy)--------------
WF中Tracking 是非常有用的,你可以想想WF的工作流引擎是个黑箱子,所有有关工作流实例运行的情况或事件只有WF引擎知道,Hosting如果想知道,那么需要一个查询的界面。Tracking就是这个查询界面,一套API模型,在WF工作流引擎内部有一个Listener监听查询请求,Tracking Profile就是查询的SQL语句,而Tracking Provider只是放查询结果的地方,可以在数据库中也可以在内存或文本中,至于你说的什么触发器这个恐怕太生硬了:) 特别是人机交互(以前的HWS场景)和状态机方式的灵活跳转的工作流场景中,比如查询任务的执行情况,或是某种状态和事件下要怎样,Tracking 是最好帮手,WF把这部分的定制留给了开发人员自己控制了,它只做内核,它的增强版本表现形式就是Biztalk Server的BAM模块,WF的设计更正了Biztalk Server 中HWS的不足,但开发上,从Beta2之后它将Tracking功能的定制放到SDK中了
---------------------End 引用---------------------
对于ccBoy的说明,我画了一个图
![](https://images.cnblogs.com/cnblogs_com/foundation/U_t.JPG)
自写义tracking服务,需要实现TrackingChannel 与TrackingServic这两个类
实现TrackingChannel (今天是单号,我用C#写)
public class Tracking通道 : TrackingChannel
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
private TrackingParameters 被跟踪的实例 = null;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//构造-2
protected Tracking通道()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{}
//构造-2
public Tracking通道(TrackingParameters parameters)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//该参数将得到TrackingParameters
//有被跟踪的实例的信息(很多)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.被跟踪的实例 = parameters;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//override
//Tracking runtime调用该方将实例完成的信息向外界抛
protected override void InstanceCompletedOrTerminated()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Console.WriteLine();
Console.WriteLine("-------------------------------------");
Console.WriteLine("实例已完成或终止");
Console.WriteLine("实例:" + 被跟踪的实例.InstanceId.ToString());
Console.WriteLine("实例为:" + 被跟踪的实例.WorkflowType.AssemblyQualifiedName);
Console.WriteLine("-------------------------------------");
Console.WriteLine();
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//override
//Tracking runtime调用该方法发送将监视到的各类tracking records向外界抛出
protected override void Send(TrackingRecord record)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// 对类型进行一下对象筛选,然后再跟据不同的对象进行不同的输出
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//筛选实例
if (record is WorkflowTrackingRecord)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
WorkflowTrackingRecord obj1 = (WorkflowTrackingRecord)record;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.WriteLine();
Console.WriteLine("-------------------------------------");
Console.WriteLine("实例记录");
Console.WriteLine("实例:" + 被跟踪的实例.InstanceId.ToString());
Console.WriteLine("时间: " + obj1.EventDateTime.ToString());
Console.WriteLine("实例状态: " + obj1.TrackingWorkflowEvent.ToString());
Console.WriteLine("-------------------------------------");
Console.WriteLine();
}
//筛选结点
if (record is ActivityTrackingRecord)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
ActivityTrackingRecord obj2 = (ActivityTrackingRecord)record;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.WriteLine();
Console.WriteLine("-------------------------------------");
Console.WriteLine("Activity记录");
Console.WriteLine("实例:" + 被跟踪的实例.InstanceId.ToString());
Console.WriteLine("时间: " + obj2.EventDateTime.ToString());
Console.WriteLine("Activity名子: " + obj2.QualifiedName.ToString());
Console.WriteLine("Activity类型: " + obj2.ActivityType);
Console.WriteLine("信息: " + obj2.ExecutionStatus.ToString());
Console.WriteLine("-------------------------------------");
Console.WriteLine();
}
//筛选业务状态点(用户状态点)
if (record is UserTrackingRecord)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
UserTrackingRecord obj3= (UserTrackingRecord)record;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Console.WriteLine();
Console.WriteLine("-------------------------------------");
Console.WriteLine("用户状态点");
Console.WriteLine("实例:" + 被跟踪的实例.InstanceId.ToString());
Console.WriteLine("时间: " + obj3.EventDateTime.ToString());
Console.WriteLine("产生该记录点所在的Activity: " + obj3.QualifiedName.ToString());
Console.WriteLine("所在Activity的类型: " + obj3.ActivityType.FullName.ToString());
Console.WriteLine("信息: " + obj3.UserData.ToString());
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//筛选业务状态点(用户状态点)中的规则
if (obj3.UserData is System.Workflow.Activities.Rules.RuleActionTrackingEvent)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{ RuleActionTrackingEvent obj3_rule = (RuleActionTrackingEvent)obj3.UserData;
Console.WriteLine("这是一个用户状态点的规则");
Console.WriteLine("规则名: " + obj3_rule.RuleName.ToString());
Console.WriteLine("规则状态: " + obj3_rule.ConditionResult.ToString());
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//Policy绑定的规则集中的每个规则都会发送一组状态,Policy有点像职责链,具体以后讲
//Policy规则是自动将信息抛出的,但在类型上算上用户状态
}
Console.WriteLine("-------------------------------------");
Console.WriteLine();
}
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
实现TrackingServic(我把筛选也写在类里了)
public class 自定义跟踪服务 : TrackingService
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
protected override bool TryGetProfile(Type workflowType, out TrackingProfile profile)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//引擎通过该方法加载监视方案
//可在该方法内为工作流模板与对应的筛选建一字典集合,
//该演示设计成所有工作流都使用同一筛选规则方式
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//参数:workflowType,传入的类型,用于在字典集合中查找对应的筛选规则
//参数:out profile,传地址抛出筛选规则
profile = 生成一个Profile();
return true; //表示找到所指定的类型对应的筛选规则
}
protected override TrackingProfile GetProfile(Guid workflowInstanceId)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//跟据实例查对应的规则
//可用字典集实现
return 生成一个Profile();
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
protected override TrackingProfile GetProfile(Type workflowType, Version profileVersionId)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//返回指定工作流模板的指定版本号的筛选规则
//参数:profileVersionId,版本号
//可用字典集实现
return 生成一个Profile();
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
protected override bool TryReloadProfile(Type workflowType, Guid workflowInstanceId, out TrackingProfile profile)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//重载指定工作流模板的筛选规则
//参数:workflowType.,
//参数:workflowInstanceId,
//参数:out profile,
profile = null;
return false;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
protected override TrackingChannel GetTrackingChannel(TrackingParameters parameters)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//用TrackingParameters参数初始化信道
return new Tracking通道(parameters);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 建立自定义的TrackingProfile 关于自定义TrackingProfile 见相关
private static TrackingProfile 生成一个Profile()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{//一个全监视的profile
TrackingProfile profile = new TrackingProfile();
profile.Version = new Version("4.3.2.1");
ActivityTrackPoint 结点跟踪点对象= new ActivityTrackPoint();
ActivityTrackingLocation location = new ActivityTrackingLocation(typeof(Activity));
location.MatchDerivedTypes = true;
foreach (ActivityExecutionStatus s in Enum.GetValues(typeof(ActivityExecutionStatus)))
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{ location.ExecutionStatusEvents.Add(s); }
结点跟踪点对象.MatchingLocations.Add(location);
profile.ActivityTrackPoints.Add(结点跟踪点对象);
UserTrackPoint 用户跟踪点对象= new UserTrackPoint();
UserTrackingLocation UserTrackingLocation标记= new UserTrackingLocation();
UserTrackingLocation标记.ActivityType = typeof(Activity);
UserTrackingLocation标记.ArgumentType = typeof(object);
UserTrackingLocation标记.MatchDerivedArgumentTypes = true;
UserTrackingLocation标记.MatchDerivedActivityTypes = true;
用户跟踪点对象.MatchingLocations.Add(UserTrackingLocation标记);
profile.UserTrackPoints.Add(用户跟踪点对象);
WorkflowTrackPoint 实例跟踪点对象= new WorkflowTrackPoint();
实例跟踪点对象.MatchingLocation = new WorkflowTrackingLocation();
foreach (TrackingWorkflowEvent workflowEvent in Enum.GetValues(typeof(TrackingWorkflowEvent)))
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{ 实例跟踪点对象.MatchingLocation.Events.Add(workflowEvent); }
profile.WorkflowTrackPoints.Add(实例跟踪点对象);
return profile;
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)