WF4 - 延迟恢复工作流程

时间:2012-10-20 09:22:54

标签: c# .net workflow-foundation-4

我正在尝试在延迟结束时自动恢复工作流程(使用延迟活动) 如果您使用WorkflowServiceHost,则会自动完成,但我正在使用WorkflowApplication。

互联网上有一些代码可以解决这个问题,这里有sample 我正在使用WorkflowApplication来实现这些目标:

  • 用户创建任务,此任务遵循工作流程
  • 用户使用重新设计的设计器设计自己的工作流程,并将他的工作流程定义保存在数据库中。
  • 每个工作流程定义可以在数据库中保存不同的版本,以允许用户修改其工作流程,并且当对任务执行操作并且需要恢复书签时,代码使用正确的版本
  • 可以使用工作流程启动任务,因此在任务表中,我存储了哪个工作流程定义以及用于此任务的版本。

我现在的问题是使用延迟活动时 使用上面链接的代码,当检测到可运行的实例时,我需要创建一个WorkflowApplication并使用LoadRunnableInstance方法来加载工作流:

if (hasRunnableWorkflows)
{

    Console.WriteLine("Found runnable workflows");
    WorkflowApplication app = new WorkflowApplication(...);
    app.InstanceStore = store;
    app.LoadRunnableInstance();
}

问题是:

  • 要调用LoadRunnableInstance,我需要创建WorkflowApplication,因此我需要将根活动提供给WorkflowApplication CTor
  • 要创建根活动,我需要知道需要从数据库加载哪个工作流程(&版本)
  • 要知道要加载哪个工作流程,我需要任务ID
  • 要知道任务ID,我需要知道工作流程ID,该工作流程ID仅在调用LoadRunnableInstance之后才可用

所以......我需要打破这个循环:)

在加载工作流程之前,有人知道如何获得工作流ID吗?

2 个答案:

答案 0 :(得分:0)

来自Microsoft wcf和wf示例的ControllingWorkflowApplications示例显示系统必须维护其工作流ID列表,以了解要从实例存储加载哪些工作流。在该示例中,它们还保留了应该能够处理您的版本的工作流xaml文件的路径。该示例不是最容易遵循的示例,但是继承自PeristenceIOParticipant的WorkflowAppication的扩展添加到WorkflowApplication。此类提取并定义将随工作流一起保存的其他数据。为了你的目的,这将是id。

instance.Extensions.Add(()=> new WorkflowDefinitionExtension(originalPath,connectionString)); //继承自PeristenceIOParticipant

答案 1 :(得分:0)

这对我有用。

当工作流运行时命中延迟活动时,将触发事件 PersistableIdle ,如果它返回 PersistableIdleAction.Persist 然后延迟活动将自动恢复。如果事件处理程序返回 PersistableIdleAction.Unload ,则延迟活动将不会恢复 自动。 这是样本,

工作流程定义:

Variable<string> name = new Variable<string>
{
    Name = "name"
};

wf = new Sequence
{
    Variables =
    {
      name
    },
    Activities =
    {
         new WriteLine()
         {
             Text = "Workflow Triggered"
         },    
         new Delay()
         {
             Duration = TimeSpan.FromSeconds(10)
         },
         new WriteLine()
         {
             Text = "Activity1 Completed"
         },
     }
 };

WorkflowApplication:

   WorkflowApplication wfApp = new WorkflowApplication(wf);
   wfApp.PersistableIdle = delegate (WorkflowApplicationIdleEventArgs e)
   {
         return PersistableIdleAction.Persist;
   };
   // Start the workflow.
   wfApp.Run();