【问题标题】:How to pass native event handler for interrupt in state pattern code如何在状态模式代码中传递本机事件处理程序以进行中断
【发布时间】:2014-03-27 14:07:56
【问题描述】:

我已经为我的 netmf 项目转向了状态模式。基于此的东西:http://www.dofactory.com/Patterns/PatternState.aspx#_self2

我有一个旋转编码器旋钮,它在每种状态下的作用都不同。

我一直在努力解决这个问题,但我什么也做不了。我不确定在哪里以及如何将中断处理程序注入每个状态以及如何调用中断处理程序的开关。如果没有状态模式,代码看起来像这样:

RotaryEncoder RE = new RotaryEncoder(pin1, pin2);//create new instance of knob
RE.OnRotationEvent += OnRotationEventHandler;//subscribe to an event handler.
//do other things
...
...

static void OnRotationEventHandler(uint data1, uint data2, DateTime time)
        {
            //do something
        }

那么,为每个状态编写单独的“OnRotationEventHandlers”的正确方法是什么?它是上下文的一部分吗?抽象基类的一部分?

感谢您的帮助!

【问题讨论】:

  • 目前尚不清楚中断是否是解决此问题的最佳机制。如果您真的想直接由中断驱动,那么您可能应该让中断通常“泵”状态机来执行。就我个人而言,当我做这样的事情时,我有一个中断处理程序将事件捕获到一个小队列中,然后在我有时间时异步处理(这在人类方面很快) - 它的工作原理很像传统的 PC 键盘子系统(并且实际上接受了来自一个代替模拟旋钮的输入)。
  • @ChrisStratton 从概念上讲,我明白你在说什么。 NetMF 还会自动对中断进行排队。我希望状态对旋转中断事件做出反应。中断可以顺时针或逆时针执行和“返回”。国家需要知道发生了什么,然后做出相应的反应。例如,State1 正在监视一个传感器,然后发生旋转事件并且它是顺时针的。状态 1 更改为状态 2。状态可以循环轮询标志,但似乎效率低下。我也可以看到其他问题..
  • 你真的需要这么复杂吗?只是枚举与状态并切换到下一个就足够了吗?你可以从那里重构它。
  • @Euphoric 也许吧,但我不太明白。你有例子吗?

标签: c# delegates embedded interrupt-handling .net-micro-framework


【解决方案1】:

我做了更多研究,这是我想出的解决方案:

我交替使用“状态”和“模式”

上下文类:

    class ModeContext
    {
    private int rotationCount;
    private string direction;
    private State state;
    public RotaryEncoder rotaryEncoderInstance;


    public ModeContext( RotaryEncoder re)
    {
        this.State = new RPMMode(this);
        rotaryEncoderInstance = re;
        re.RotationEventHandler += OnRotationEvent;//attach to Context's Handler
        rotationCount = 0;
    }

    public State State
    {
        get { return state; }
        set { state = value; }//debug state change
    }

    //Event Handler        
    public void OnRotationEvent(uint data1, uint data2, DateTime time)
    {
        rotationCount++;
        if (data1 == 1) 
        { 
            direction = "Clockwise";
            state.OnCWRotationEvent(this);
        }
        else
        { 
            direction = "Counter-Clockwise";
            state.OnCCWRotationEvent(this);
        }
        Debug.Print(rotationCount.ToString() + ": " + direction + " Context Mode Rotation Event Fired!");
    }

继承状态基类的具体状态类:

        class Mode2 : State
        {
        public override void Handle(ModeContext mode)
        {
            mode.State = new Mode2();//(mode);
        }

        public Mode2()
        {
            //do something;   
        }
        #region event handlers
        public override void OnCWRotationEvent(ModeContext mode)
        {
            mode.State = new Mode3(mode);
        }

        public override void OnCCWRotationEvent(ModeContext mode)
        {
            mode.State = new Mode1(mode);
        }
        #endregion
    }

现在我可以更改状态并为每个状态提供特定的控制行为,那么实际的繁重工作在哪里?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多