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


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

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

           SqlTrackingService 服务还会在其数据库中保留跟踪配置文件。 工作流运行时引擎知道对所使用的任何跟踪配置文件所做的更改。 SqlTrackingService 服务实现 IProfileNotification 接口,并定期检查其数据库中的跟踪配置文件,以便将对其数据库中存储的 TrackingProfile 所做的更改通知工作流运行时引擎。 可以设置 ProfileChangeCheckInterval 属性或将适当的参数传递给构造函数来设置间隔,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来重新整理连接中的属性和变量。可以看出一次跟踪对数据库的开销还是挺大的,这在实际应用中应该要考虑清楚。

             如果在工作流应用程序中同时使用 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();
                }
           
            }

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

  • 相关阅读:
    BizTalk2010动手实验(二)第一个BizTalk应用
    基于NopCommerce的开源电商系统改造总结
    BizTalk动手实验(六)Orchestration开发
    BizTalk动手实验(三)BizTalk开发综合实验
    项目管理-自上而下还是自下而上的沟通?
    BizTalk 2013 Beta 新特性介绍
    自主开发与带兵打仗
    Word邮件合并IT男必备技能
    三年项目管理,三个阶段
    BizTalk动手实验(八)消息路由
  • 原文地址:https://www.cnblogs.com/ASPNET2008/p/1401010.html
Copyright © 2020-2023  润新知