【问题标题】:Statefinalization/initialization activity only runs on leaf states状态终结/初始化活动仅在叶状态上运行
【发布时间】:2009-11-25 12:26:39
【问题描述】:

我正在尝试让我的 Windows 状态机工作流程与最终用户进行通信。我试图在 StateActivity 中实现的一般模式是:

StateInitializationActivity:向用户发送消息,请求回答问题(例如“您批准此文档吗?”),以及...的上下文
...EventDrivenActivity:处理用户发送的答案
StateFinalizationActivity:取消消息(例如文档被撤回,不再需要批准)

如果 StateActivity 是“叶状态”(即没有子状态),这一切都可以正常工作。但是,如果我想使用状态的递归组合,它就不起作用。对于非叶状态,StateInitialization 和 StateFinalization 不会运行(我通过使用 Reflector 检查 StateActivity 源代码确认了这种行为)。 EventDrivenActivity 仍在监听,但最终用户不知道发生了什么。

对于 StateInitialization,我认为解决此问题的一种方法是将其替换为 EventDrivenActivity 和零延迟计时器。我不知道如何处理 StateFinalization。

那么 - 有没有人知道如何让 State Finalization Activity 始终运行,即使对于非叶状态也是如此?

【问题讨论】:

  • 你能详细说明“状态的递归组合”吗?什么是递归的?
  • 这是我在有关该主题的书籍和文章中看到的一个术语。它只是意味着一个 StateActivity 可以包含其他 StateActivity。子状态未处理的事件将传递给父状态以供其处理。我想这取决于你所说的“递归”是什么意思。

标签: recursion workflow workflow-foundation finalizer state-machine


【解决方案1】:

不幸的是,“嵌套状态”的结构是包含“子级”的“父级”之一,设计器 UI 重新执行了这个概念。因此,以您的思维方式思考是非常自然和直观的。这是不幸的,因为它是错误的。

真正的关系是“一般”->“特定”之一。它实际上是一个层次结构的类结构。考虑一个更熟悉的关系:-

public class MySuperClass
{
    public MySuperClass(object parameter) { }
    protected void DoSomething() { }
}

public class MySubClass : MySuperClass
{
    protected void DoSomethingElse() { }
}

这里的MySubClass 继承自SuperClassDoSomething。上面的内容被破坏了,因为SuperClass 没有默认构造函数。 SuperClass 的参数化构造函数也不会被 SubClass 继承。事实上,从逻辑上讲,子类永远不会继承超类的构造函数(或析构函数)。 (是的,默认构造函数有一些神奇的连接方式,但糖多于实质)。

同样,包含的StateAivities 与另一个StateActivity 之间的关系实际上是包含的活动是容器的专业化。每个包含的活动都继承了容器的一组事件驱动活动。但是,每个包含的 StateActivity 都是与任何其他状态相同的工作流中的第一类离散状态。

包含的活动实际变成了一个抽象,它不能被转换到,重要的是没有转换到另一个状态“内部”的状态的真正概念。通过扩展,也没有离开这种外部状态的概念。因此,包含的 StateActivity 没有初始化或完成。

设计器的一个怪癖允许您添加 StateInitialization 和 StateFinalization 然后将 StateActivities 添加到状态。如果你反过来尝试,设计器不会让你这样做,因为它知道初始化和终结将永远不会运行。

我意识到这实际上并不能回答你的问题,在这种情况下我不愿意说“它不能完成”,但如果可以的话,它会有点 hacky。

【讨论】:

  • 有趣的帖子安东尼,看来你已经考虑了很多!虽然它有一些怪癖,但你会说stateless.googlecode.com 实现了你喜欢的模型吗?例如。 blogs.msdn.com/nblumhardt/archive/2009/04/16/… 中显示的“已连接”状态?我非常感谢您对有关此主题的其他材料的任何指示。尼克
  • @Nick:感谢您提供非常有趣的链接。作为开发人员,我会说是的,从开发人员的角度来看,Stateless 似乎是一种比 Workflow 中的方法更好的构建状态机的方法。然而,Workflow 针对不同的受众,同时试图让开发人员参与其中,其真正针对的是精通技术的领域专家。也就是说,Workflow UI 在传达包含状态的性质方面做得很差,甚至对于更高级的业务任务,Workflow 旨在实现真正嵌套机器的想法。
  • 感谢您的回复。我认为 WF 确实有一些转换进出父“超级状态”的概念,因为这些在跟踪服务中被记录为“执行”和“关闭”活动事件。 “无状态”正是我正在寻找的行为,我认为电话示例非常有启发性。我很困惑为什么 WF 状态机在这方面受到限制。
【解决方案2】:

好的,这就是我最终决定做的事情。我创建了一个自定义跟踪服务,它查找与进入或离开与最终用户通信相关的状态相对应的活动事件。此服务在进入状态时将用户的决策输入数据库,并在状态离开时将其删除。用户可以查询数据库以查看工作流正在等待哪些决策。工作流使用 EventDrivenActivity 中的 ReceiveActivity 侦听用户响应。这也适用于父“超级国家”的决策。这可能不完全是“跟踪服务”的用途,但它似乎有效

【讨论】:

    【解决方案3】:

    我想到了另一种解决问题的方法。最初,我想在通信方面我会使用 WF 3.5 中提供的 WCF 集成的 SendActivity 和 ReceiveActivity。

    但是,最后我得出的结论是,忽略这些活动并使用本地服务实现自己的 IEventActivity 会更容易。 IEventActivity.Subscribe 可用于向用户指示有问题需要他们回答,而 IEventActivity.Unsubscribe 可用于取消该问题。这意味着不需要在州的初始化和完成块中进行单独的活动。使用工作流队列手动完成消息路由,并将用户的响应添加到具有适当名称的队列中。我使用 Guid 的队列名称,这些在 IEventActivity.Subscribe 调用期间传递给用户。

    我使用 MSDN 中的“文件系统观察程序”示例来确定如何执行此操作。 我也觉得这篇文章很有启发性:http://www.infoq.com/articles/lublinksy-workqueue-mgr

    【讨论】:

      猜你喜欢
      • 2019-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-13
      • 2019-01-04
      • 1970-01-01
      相关资源
      最近更新 更多