Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 工作流设计困境-状态机,是或否_C#_.net_Workflow_Workflow Foundation - Fatal编程技术网

C# 工作流设计困境-状态机,是或否

C# 工作流设计困境-状态机,是或否,c#,.net,workflow,workflow-foundation,C#,.net,Workflow,Workflow Foundation,我是WF的初学者,但我读过一本书,也做过很多谷歌搜索。我想写一个库存管理服务。库存由具有以下状态的单个项目组成: 备用 安装 修复中 物品可能在每个州停留数月,并且有数千件物品 问题是,我是否为所有不同的状态创建状态机工作流?或者我要创建用于在状态之间转换的工作流 如果我理解正确,如果我创建一个单一的状态机工作流,那么每个项目都将始终运行一个工作流。这意味着成千上万的工作流程一直在运行。此外,我还需要能够显示每个项目状态的快照,这意味着我必须以某种方式查询所有工作流的当前状态,或者在每个状态转换

我是WF的初学者,但我读过一本书,也做过很多谷歌搜索。我想写一个库存管理服务。库存由具有以下状态的单个项目组成:

  • 备用
  • 安装
  • 修复中
  • 物品可能在每个州停留数月,并且有数千件物品

    问题是,我是否为所有不同的状态创建状态机工作流?或者我要创建用于在状态之间转换的工作流

    如果我理解正确,如果我创建一个单一的状态机工作流,那么每个项目都将始终运行一个工作流。这意味着成千上万的工作流程一直在运行。此外,我还需要能够显示每个项目状态的快照,这意味着我必须以某种方式查询所有工作流的当前状态,或者在每个状态转换后保留到数据库

    然而,从逻辑上讲,状态机工作流似乎是正确的做法,因此我陷入了困境

    如果可以,请帮助我:-)

    谢谢

    更新:

    假设我的状态比上述3个多,并且并非所有的状态转换都是可能的


    <强>赏金赢家:毛里斯 -感谢所有其他人真正帮助我更多地了解工作流、MS工作流基础和其他更轻量级的替代品。不幸的是,赏金赢家只能有一个,莫里斯的回答及其评论对我帮助最大。

    尽管状态机模式在技术上是正确的选择,但也有一个选项可以创建带有一个巨大循环的顺序工作流。在某些情况下,它实际上工作得更好,更容易理解。

    您有三种不同的状态,就我所见,所有转换都是允许的。考虑到这一点,我不会为状态机而烦恼,因为状态机是一段检查允许的转换并向前推进的代码

    当状态驱动业务时,或者当需要一段受信任的代码作为负责“有效转换”的唯一参与者时,状态机是有意义的


    更简单地说,您只需要在任何时间点具有给定状态的实体…

    Aviad,我同意您的意见,即工作流应该在状态之间。正在盘点的零件的状态听起来像是项目的状态/属性。该状态几乎可以以任何方式存储(例如数据库、文件…),因为项目在状态之间的移动将存在于业务逻辑层中

    听起来像是一个有趣的项目,祝你好运。

    考虑到你添加的内容(超过3个州,并非所有的转换都允许),我将执行以下操作:

  • 将每个项目的状态存储在项目本身中。
    这很容易做到:向类中添加成员或向表中添加列等,其他人在其帖子/评论中已经提到了这一点
  • 使用一个状态机(可以是从类实例到具有合法转换的表的任何内容),它保存您的业务逻辑,即状态之间允许的转换以及当项目更改其状态时要执行的其他操作的知识

  • 然后,您所需要做的就是使用状态机转换您的项目,每当发生外部事件时,这就强制/暗示了这一点。

    不确定工作流是否是您首先要寻找的

    工作流是发生的某种业务流程。这意味着这个过程的开始和结束。您的描述听起来更像是在跟踪库存中的物品

    当项目更改状态时,工作流听起来更合适。例如,当一个项目已安装并发生故障,需要修复时,您将启动一个工作流,以将该零件更换为工作零件,将损坏的零件发送给维修人员,最后将其作为固定备件送回仓库。工作流将描述此过程,并从项目损坏的报告开始,以项目修复或丢弃和更换结束

    最后一个工作流很可能是一个状态工作流,因为该项目经历了以下各个阶段:

    • 断断续续
    • 破损和更换
    • 在商店里修理
    • 修复

      • 好的。让我们看看我能不能帮你。让我们从设计开始:

        设计一个状态机和一个工作流是有意义的。这两种观点只是对你的问题的不同看法,从不同的角度揭示了一些问题。事实上,经常发生的情况是,对工作流不熟悉的开发人员设计状态机而不是工作流流程。工作流流程视图主要切换图表中方框和转换的角色:方框是可以更改状态的活动-在转换时,工作项可以进入新状态(好的,这在科学上不正确,但可能有帮助:-)

        对我来说,状态机方面似乎更重要。因此,将您的软件实现为状态机

        是的,您应该使数据库中的所有项持久化。这也是保持长时间运行的工作流运行的方式——它们一直存在于数据库中,直到被任何活动重新激活。所有现成的业务流程管理系统(BPMS)都是这样做的。这些工作流不会保存在内存中

        将所有内容都保存在数据库中,可以轻松创建报告

        正如其他人已经提到的,用状态信息创建一个新列,甚至用元数据创建一个新表:state,可能是状态改变时的日志,谁改变了状态,关于即将发生的事件的信息(零件已订购但未交付-如果交付丢失,应在多少天后与供应商进行检查?)。这将使您有机会根据需要添加元数据
        var phoneCall = new StateMachine<State, Trigger>(State.OffHook);
        
        phoneCall.Configure(State.OffHook)
            .Permit(Trigger.CallDialed, State.Ringing);
        
        phoneCall.Configure(State.Ringing)
            .Permit(Trigger.HungUp, State.OffHook)
            .Permit(Trigger.CallConnected, State.Connected);
        
        phoneCall.Configure(State.Connected)
            .OnEntry(() => StartCallTimer())
            .OnExit(() => StopCallTimer())
            .Permit(Trigger.LeftMessage, State.OffHook)
            .Permit(Trigger.HungUp, State.OffHook)
            .Permit(Trigger.PlacedOnHold, State.OnHold);
        
        // ...
        
        phoneCall.Fire(Trigger.CallDialled);
        Assert.AreEqual(State.Ringing, phoneCall.State);
        
        var stateMachine = new StateMachine<State, Trigger>(
            () => myState.Value,
            s => myState.Value = s);