一起学WF3.5【8】

前文我们尝试添加了SqlTrackingService服务,运行后观察了数据库的变化。本节将这个例子丰富并完成。

检索来自于工作流中的跟踪记录

打开上节创建的WorkflowTracker工程的Program.cs文件,声明以下空间:

UsingSystem.Configuration;
UsingSystem.Workflow.Runtime.Tracking;
 

在Main方法的 waitHandle.WaintOne();后添加:

ShowWorkflowTrackingEvents(instance.InstanceId);
ShowActivityTrackingEvents(instance.InstanceId);

这是两个不存在的方法,我们需要添加如下代码。

 

static voidShowActivityTrackingEvents(Guid instanceId)
       {
           SqlTrackingQuery sqlTrackingQuery = newSqlTrackingQuery(ConfigurationManager.ConnectionStrings["TrackingDatabase"].ConnectionString);
 
           SqlTrackingWorkflowInstance sqlTrackingWorkflowInstance = null;
           sqlTrackingQuery.TryGetWorkflow(instanceId, outsqlTrackingWorkflowInstance);
           if (sqlTrackingWorkflowInstance != null)
           {
               Console.WriteLine("\nActivity Tracking Events:\n");
                Console.WriteLine("  Status :: Date/Time :: Qualified ID");
 
               foreach(ActivityTrackingRecord atr in sqlTrackingWorkflowInstance.ActivityEvents)
                {
                   Console.WriteLine("  {0} ::{1} :: {2}", atr.ExecutionStatus, atr.EventDateTime, atr.QualifiedName);
                } // foreach
            } // if
       }
 
       static void ShowWorkflowTrackingEvents(Guid instanceId)
       {
           SqlTrackingQuery sqlTrackingQuery = newSqlTrackingQuery(ConfigurationManager.ConnectionStrings["TrackingDatabase"].ConnectionString);
 
           SqlTrackingWorkflowInstance sqlTrackingWorkflowInstance = null;
           sqlTrackingQuery.TryGetWorkflow(instanceId, outsqlTrackingWorkflowInstance);
           if (sqlTrackingWorkflowInstance != null)
           {
                Console.WriteLine("\nWorkflowInstance Events:\n");
                Console.WriteLine("  Description :: Date/Time");
 
                foreach (WorkflowTrackingRecordworkflowTrackingRecord in sqlTrackingWorkflowInstance.WorkflowEvents)
                {
                   Console.WriteLine("  {0} :: {1}",workflowTrackingRecord.TrackingWorkflowEvent,workflowTrackingRecord.EventDateTime);
                } // foreach
           }
       }

 

上述代码并不复杂,我们首先创建了一SqlTrackingQuery的实例,为它提供数据库连接字符串。然后我们通过当前工作流实例ID,从数据库中查询该实例的跟踪信息。查询由SqlTrackingService.TryGetWorkflow执行。假如数据库中有指定工作流的信息,我们循环获取跟踪记录。查询返回给我们的是一个workflowTrackingRecord对象的集合,从中提取需要的信息。编译,运行,在控制台查看输出。

跟踪用户事件

SqlTrackingService是WF的一部分,它可以跟踪活动和工作流激发的标准事件。

Activity活动支持一个名叫TrackData的方法,执行它并为跟踪传入通常是字符串类型的数据,将作为用户事件数据存入跟踪数据库。

 

在Workflow1.cs,找到PreDelayMessage方法,添加

this.TrackData(“Delaycommencing”);

找到PostDelayMessage方法,添加

this.TrackData(“Delaycomplete”);

编译执行。打开WorkflowTracking数据表中的UserEvent表。我们在工作流中每调用一次TrackData就产生一条记录。

 

创建自定义配置文件

通过定义跟踪配置文件来限制存储到跟踪数据库中的信息,它规定一个给定的工作流的跟踪将包含和排除的东西。使用TrackingProfile对象及其他可用对象来创建这个XML文档。

在”事件跟踪对象“表中带有location或point的对象,location指在你的工作流中活动、工作流或用户事件发生时一个指定的位置。Locations描述了要跟跟踪的事件,使用它能精确地指定你想跟踪或排除的事件。你可把跟踪点当成一个感兴趣的点,能在你的工作流代码中跨越不同的位置。

当我们建立跟踪配置文件时,就是要把跟踪点和位置添加到profile对象中作为跟踪事件的过滤器使用。

 

创建一个新的跟踪配置文件

打开WorkflowTracker的Program.cs,加入如下空间声明:

usingSystem.Workflow.ComponentModel;
usingSystem.Data;
usingSystem.Data.SqlClient;
usingSystem.Globalization;
usingSystem.IO;

在Main方法中创建工作流的代码前,添加如下代码:

TrackingProfile profile = CreateProfile();
StoreProfile(profile, ConfigurationManager.ConnectionStrings["TrackingDatabase"].ConnectionString);

定义上述两个函数:

static TrackingProfile CreateProfile()
        {
            //Create the basic profile
           TrackingProfile profile = new TrackingProfile();
 
            //Create the activity location, meaning the events we're interested in
           ActivityTrackingLocation actLoc = newActivityTrackingLocation(typeof(Activity));
           actLoc.MatchDerivedTypes = true;
           actLoc.ExecutionStatusEvents.Add(ActivityExecutionStatus.Executing);
 
            //Create the activity track point and add the location we just created
           ActivityTrackPoint actPt = new ActivityTrackPoint();
           actPt.MatchingLocations.Add(actLoc);
           profile.ActivityTrackPoints.Add(actPt);
 
            //Create the workflow location
           WorkflowTrackingLocation wfLoc = new WorkflowTrackingLocation();
           wfLoc.Events.Add(TrackingWorkflowEvent.Started);
           wfLoc.Events.Add(TrackingWorkflowEvent.Idle);
 
            //Create the workflow track point
           WorkflowTrackPoint wfPt = new WorkflowTrackPoint();
           wfPt.MatchingLocation = wfLoc;
           profile.WorkflowTrackPoints.Add(wfPt);
 
            //Set the version of the profile...this version must not already exist
            //in the database.
           profile.Version = new Version("1.0.0.0");
           return profile;
        }
 
        staticvoid StoreProfile(TrackingProfile profile, string connString)
        {
            //First, serialize the profile into an XML string
           TrackingProfileSerializer serializer = new TrackingProfileSerializer();
           StringWriter writer = new StringWriter(new StringBuilder(),CultureInfo.InvariantCulture);
           serializer.Serialize(writer, profile);
 
            //Then, write the XML string to the database
           SqlConnection conn = null;
            try
            {
               if (!String.IsNullOrEmpty(connString))
               {
                   // Create a connection object
                   conn = new SqlConnection(connString);
 
                   // Create a dummy for the stored proc name
                    string storedProc ="dbo.UpdateTrackingProfile";
 
                   // Create the command
                   SqlCommand cmd = new SqlCommand(storedProc, conn);
                   cmd.CommandType = CommandType.StoredProcedure;
 
                   // Add the parameters
                   SqlParameter parm = new SqlParameter("@TypeFullName",SqlDbType.NVarChar, 128);
                   parm.Direction = ParameterDirection.Input;
                   parm.Value = typeof(TrackedWorkflow.Workflow1).ToString();
                   cmd.Parameters.Add(parm);
                   parm = new SqlParameter("@AssemblyFullName",SqlDbType.NVarChar, 256);
                   parm.Direction = ParameterDirection.Input;
                   parm.Value = typeof(TrackedWorkflow.Workflow1).Assembly.FullName;
                   cmd.Parameters.Add(parm);
                   parm = new SqlParameter("@Version", SqlDbType.VarChar, 32);
                   parm.Direction = ParameterDirection.Input;
                   parm.Value = "1.0.0.0";
                   cmd.Parameters.Add(parm);
                   parm = new SqlParameter("@TrackingProfileXml",SqlDbType.NText);
                   parm.Direction = ParameterDirection.Input;
                   parm.Value = writer.ToString();
                   cmd.Parameters.Add(parm);
 
                   // Open the connection
                   conn.Open();
 
                   // Write the XML data
                   cmd.ExecuteNonQuery();
                } // if
            }// try
           catch (Exception ex)
            {
               // If the exception is telling us we've already written
               // this profile to the database, just pop up an informational
               // message.
               if (ex is SqlException)
               {
                   // Check to see if it's a version error
                   if (ex.Message.Contains("已经存在大于或等于新版本的版本"))
                   {
                        // Version alreadyexists...
                       Console.WriteLine("NOTE: a profile with the same version alreadyexists in the database.");
                   } // if
                   else
                   {
                        // Write error message
                       Console.WriteLine("Error writing profile to database: {0}",ex.ToString());
                   } // else
               } // if
               else
               {
                   // Write error message
                   Console.WriteLine("Error writing profile to database: {0}",ex.ToString());
               } // else
            }// catch
           finally
            {
               // Close the connection
                if (conn != null)
               {
                   conn.Close();
               } // if
            }// finally
        }

我们用CreateProfile方法创建了一个新的TrackingProfile并添加了一个活动跟踪点和工作流跟踪点。每个跟踪点都有一个单一的位置,它只定义了要跟踪来自活动Executing事件和来自工作流实例的Started事件和Idle事件。

用StoreProfile方法,把跟踪配置文件序列化成XML形式,然后用ADO.NET技术把这个XML存入跟踪数据库。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值