这篇我来为asp.net中的报销多级审批工作流项目加上跟踪服务。

类表示一个功能完全的跟踪服务。 使用此服务可以收集和存储跟踪信息,还可以存储跟踪配置文件,并在工作流运行时引擎请求时提供这些配置文件。 SQL 跟踪服务将运行时跟踪基础结构发送给它的跟踪数据写入到 SQL 数据库。 在许多情况下,对于 SqlTrackingService 服务来说,保持其数据库和工作流运行时引擎状态之间的一致性十分重要。 因此,SqlTrackingService 类实现了 接口,并可参与到由 服务提供的工作流事务批处理功能中。 您可以设置 属性,或将适当的参数传递给构造函数,以便将 SqlTrackingService 服务配置为参与批处理,并将表示 SQL 数据库挂起更改的对象添加到工作批次。

       SqlTrackingService 服务还会在其数据库中保留跟踪配置文件。 工作流运行时引擎知道对所使用的任何跟踪配置文件所做的更改。 SqlTrackingService 服务实现 接口,并定期检查其数据库中的跟踪配置文件,以便将对其数据库中存储的 所做的更改通知工作流运行时引擎。 可以设置 属性或将适当的参数传递给构造函数来设置间隔,SqlTrackingService 服务将按该间隔检查其跟踪配置文件。[MSDN]    

       第一:配置跟踪用的数据库。

               在C:\WINDOWS\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\EN目录下有两个文件Tracking_Schema.sql和Tracking_Logic.sql,安先后顺序执行。
       第二:配置跟踪服务。配置文件如下:

<?xml version="1.0" encoding="utf-8" ?>
 
<configuration>
   
<configSections>
   
<section name="WorkflowWithTracking"
   type
="System.Workflow.Runtime.Configuration.WorkflowRuntimeSection, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   
</configSections>
   
<WorkflowWithTracking>
   
<CommonParameters>
   
<add name="ConnectionString"
   value
="Data Source=.;Initial Catalog=c6ps;Integrated Security=True"/>
   
</CommonParameters>
   
<Services>
   
<add type="System.Workflow.Runtime.Tracking.SqlTrackingService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35"/>
   
</Services>
   
</WorkflowWithTracking>
 
</configuration>

      

        第三:修改封装的WorkflowWrapper类,在实例化WorkflowRuntime时加入跟踪服务。

static SqlTrackingService _SqlTrackingService;//跟踪服务
_SqlTrackingService = new SqlTrackingService(ConfigurationManager.ConnectionStrings["perstr"].ConnectionString);
if (runtime.GetService(_SqlTrackingService.GetType()) == null)
            {
                
//加入跟踪服务
                runtime.AddService(_SqlTrackingService);
            }

 

        说明:这个调用代码要在整个工作流的最后调用,否则跟踪不到任何信息,在本项目中就是财务审批的地方,如果放在员工提交审批的地方是不能调出任何信息的。

        下面是页面输出的信息:

Tracking Information for 56b0e92a-d1fd-4770-be83-2c088e518dc7 
Workflow Events Date: 
2009-3-1 9:10:43
Status: Created Date: 
2009-3-1 9:10:43
Status: Started Date: 
2009-3-1 9:10:57
Status: Unloaded Date: 
2009-3-1 9:10:57
Status: Persisted Date: 
2009-3-1 9:13:40,
Status: Loaded Date: 
2009-3-1 9:13:40,
Status: Idle Date: 
2009-3-1 9:13:40
Status: Unloaded Date: 
2009-3-1 9:13:40,
Status: Persisted Date: 
2009-3-1 10:31:43,
Status: Loaded Date: 
2009-3-1 10:31:43
Status: Unloaded Date: 
2009-3-1 10:31:43
Status: Persisted Date: 
2009-3-1 10:31:45
Status: Loaded Date: 
2009-3-1 10:31:45
Status: Idle Date: 
2009-3-1 10:31:45
Status: Unloaded Date: 
2009-3-1 10:31:45
Status: Persisted Activity Events Activity: Workflow1 Date: 
2009-3-1 9:10:43 
Status: Executing Activity: whileActivity1 Date: 
2009-3-1 9:13:40 
Status: Executing Activity: sequenceActivity1 Date: 
2009-3-1 9:13:40 
Status: Executing Activity: listenActivity1 Date: 
2009-3-1 9:13:40 
Status: Executing Activity: eventDrivenActivity1 Date: 
2009-3-1 9:13:40 
Status: Executing Activity: OnStaffSubmit Date: 
2009-3-1 9:13:40 
Status: Executing Activity: OnStaffSubmit Date: 
2009-3-1 9:13:40 
Status: Closed Activity: eventDrivenActivity1 Date: 
2009-3-1 9:13:40 
Status: Closed Activity: listenActivity1 Date: 
2009-3-1 9:13:40 
Status: Closed Activity: sequenceActivity1 Date: 
2009-3-1 9:13:40 
Status: Closed Activity: sequenceActivity1 Date: 
2009-3-1 9:13:40 
Status: Executing Activity: listenActivity1 Date: 
2009-3-1 9:13:40 
Status: Executing Activity: eventDrivenActivity3 Date: 
2009-3-1 10:31:43 
Status: Executing Activity: OnPMSubmitMin Date: 
2009-3-1 10:31:45 
Status: Executing Activity: OnPMSubmitMin Date: 
2009-3-1 10:31:45 
Status: Closed Activity: eventDrivenActivity3 Date: 
2009-3-1 10:31:45 
Status: Closed Activity: listenActivity1 Date: 
2009-3-1 10:31:45 
Status: Closed Activity: sequenceActivity1 Date: 
2009-3-1 10:31:45 
Status: Closed Activity: sequenceActivity1 Date: 
2009-3-1 10:31:45 
Status: Executing Activity: listenActivity1 Date: 
2009-3-1 10:31:45 
Status: Executing

 

        注意:跟踪服务是和数据库打交道的,我们需要清楚它的系统开销,这里为了简单我们创建一个控制台的工作流,工作流中拉入一个codeActivity,执行代码为:

 private void codeActivity1_ExecuteCode(object sender, EventArgs e)
        {
            Console.WriteLine(
"codeActivity1执行了!");
           
        }

 

        客户端程序代码为:

//数据库连接串
        private static String strConn = "";
        
static void Main(string[] args)
        {
            WorkflowRuntimeSection config;
            config 
= ConfigurationManager.GetSection("WorkflowWithTracking"as WorkflowRuntimeSection;
            
//数据库连接串
            strConn = config.CommonParameters["ConnectionString"].Value;
            
using (WorkflowRuntime workflowRuntime = new WorkflowRuntime("WorkflowWithTracking"))
            {
                SqlTrackingService sts 
= new SqlTrackingService(strConn);
                AutoResetEvent waitHandle 
= new AutoResetEvent(false);
                workflowRuntime.WorkflowCompleted 
+= delegate(object sender, WorkflowCompletedEventArgs e) { waitHandle.Set(); };

                
if (workflowRuntime.GetService(sts.GetType()) == null)
                {
                    
//加入跟踪服务
                    workflowRuntime.AddService(sts);
                }

                WorkflowInstance instance 
= workflowRuntime.CreateWorkflow(typeof(ApproveWorkFlow.WorkflowConsole.Workflow1));
              
                instance.Start();
                waitHandle.WaitOne();
             
                Console.WriteLine(
"---DumpTrackingEvents开始---");
                DumpTrackingEvents(instance.InstanceId);
                Console.WriteLine(
"---DumpTrackingEvents结束---");
                Console.Read();
            }
       
        }

 

         下面是数据库的跟踪图:从图中的红圈中可以看到有六次sp_reset_connection,它的定义是存储过程由 SQL Server 用来支持事务中的远程存储过程调用。SqlConnection.Open一次,就调用sp_reset_connection来重新整理连接中的属性和变量。可以看出一次跟踪对数据库的开销还是挺大的,这在实际应用中应该要考虑清楚。

asp.net中的报销多级审批工作流项目加上跟踪服务

 

         如果在工作流应用程序中同时使用 SqlTrackingService 和 SqlWorkflowPersistenceService,建议为持久性和跟踪使用单一数据库。运行时引擎启动后,如果没有添加其他 WorkflowCommitWorkBatch 服务,则 WorkflowRuntime 类将创建 DefaultWorkflowCommitWorkBatchService 对象。 可以在工作流中使用此服务以支持数据完整性所需的工作批次。 也可以选择使用SharedConnectionWorkflowCommitWorkBatchService 服务。 此服务用于在不同对象之间使用共享连接的数据库事务。 若要在 WorkflowRuntime 实例中使用 SharedConnectionWorkflowCommitWorkBatchService 服务而不是 DefaultWorkflowCommitWorkBatchService 服务,请使用 AddService 方法。[MSDN]

        配置节点:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<configSections>
    
<section name="WorkflowWithTracking"
  type
="System.Workflow.Runtime.Configuration.WorkflowRuntimeSection, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  
</configSections>
  
<WorkflowWithTracking>
    
<CommonParameters>
      
<add name="ConnectionString"
      value
="data source=.;database=SqlPersistenceService;persist security info=False;user id=sa;pwd=sa; packet size=4096;"/>
    
</CommonParameters>
    
<Services>
      
<add type="System.Workflow.Runtime.Tracking.SqlTrackingService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35"/>
      
<add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  UnloadOnIdle
="true" />
      
<add type= "System.Workflow.Runtime.Hosting.SharedConnectionWorkflowCommitWorkBatchService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

    
</Services>
  
</WorkflowWithTracking>

</configuration>

 

          客户端代码:

private static String strConn = "";
        
static void Main(string[] args)
        {
            WorkflowRuntimeSection config;
            config 
= ConfigurationManager.GetSection("WorkflowWithTracking"as WorkflowRuntimeSection;
            
//数据库连接串
            strConn = config.CommonParameters["ConnectionString"].Value;
            
using (WorkflowRuntime workflowRuntime = new WorkflowRuntime("WorkflowWithTracking"))
            {
                SqlTrackingService sts 
= new SqlTrackingService(strConn);
                AutoResetEvent waitHandle 
= new AutoResetEvent(false);
                workflowRuntime.WorkflowCompleted 
+= delegate(object sender, WorkflowCompletedEventArgs e) { waitHandle.Set(); };
                SharedConnectionWorkflowCommitWorkBatchService _shareConn 
= new SharedConnectionWorkflowCommitWorkBatchService(strConn);
                
if (workflowRuntime.GetService(_shareConn.GetType()) == null)
                {
                    
//加入数据连接共享服务
                    workflowRuntime.AddService(_shareConn );
                }

                
if (workflowRuntime.GetService(sts.GetType()) == null)
                {
                    
//加入跟踪服务
                    workflowRuntime.AddService(sts);
                }
                SqlWorkflowPersistenceService perService 
= new SqlWorkflowPersistenceService(strConn);
                
if (workflowRuntime.GetService(perService.GetType()) == null)
                {
                    
//加入持久化服务
                    workflowRuntime.AddService(perService);
                }
                WorkflowInstance instance 
= workflowRuntime.CreateWorkflow(typeof(ApproveWorkFlow.WorkflowConsole.Workflow1));
              
                instance.Start();
                waitHandle.WaitOne();
             
                Console.WriteLine(
"---DumpTrackingEvents开始---");
                DumpTrackingEvents(instance.InstanceId);
                Console.WriteLine(
"---DumpTrackingEvents结束---");
                Console.Read();
            }
       
        }

   
         问题:我同时添加了持久化服务和跟踪服务,也启动了共享数据库连接服务,再次跟踪数据库,发现情况和之前的跟踪服务一样,这是我不明白的地方,希望哪位高手帮忙指点下。

相关文章: