从另一个呼叫一个事件

时间:2018-07-30 20:16:07

标签: c# .net events

我正在尝试为计时器创建一个抽象层。基本上,这个想法是创建一个抽象两个单独计时器的类。基本上,计时器抽象类应在“关闭”时触发一个事件,而在“打开”时触发另一个事件。因此,例如,如果这是一个交通信号灯,计时器1将控制绿灯,计时器2将控制红色(让我们忽略黄色)。

如您所见,timer1_Elapsedtimer2_Elapsed处理计时器的“菊花链”。这些事件发生后,我希望另一个事件(此计时器的真正目的”发生。

问题似乎是我的Event1Event2 ElapsedEventHandler似乎无法正常工作。我收到以下错误: 'TwoCycleTimer.Event1.get' must declare a body because it is not marked abstract, extern, or partialEvent2

一样

我应该指出,声明get的主体没有任何作用,只会使情况变得更糟。

get {return timer1.Elapsed; };导致can only appear on the left hand side of += or =错误

using System;
using System.Timers;

public class TwoCycleTimer
{
    private Boolean enabled;    
    private Timer timer1;
    private Timer timer2;

public Boolean Enabled
{
    get { return enabled; }
    set 
    {
        timer1.Enabled = value;
        enabled = value;
    }
}

public double Interval1
{
    get { return timer1.Interval; }
    set { timer1.Interval = value; }
}

public double Interval2
{
    get { return timer2.Interval; }
    set { timer2.Interval = value; }
}

public ElapsedEventHandler Event1 { get; set { timer1.Elapsed += value; } }
public ElapsedEventHandler Event2 { get; set { timer2.Elapsed += value; } }

public TwoCycleTimer(bool Enabled = false, double Interval1 = 4000, double Interval2 = 60000, ElapsedEventHandler Event1 = null, ElapsedEventHandler Event2 = null)
{
    timer1 = new Timer(Interval1);
    timer2 = new Timer(Interval2);

    timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
    timer2.Elapsed += new ElapsedEventHandler(timer2_Elapsed);


    if(Event1 != null)
        timer1.Elapsed += Event1;
    if(Event2 != null)
        timer2.Elapsed += Event2;

    this.Enabled = enabled;
}

private void timer1_Elapsed(object source, ElapsedEventArgs e)
{
    if (Enabled)
    {
        timer1.Enabled = false;
        timer2.Enabled = true;
    }
}

private void timer2_Elapsed(object source, ElapsedEventArgs e)
{
    if (Enabled)
    {
        timer2.Enabled = false;
        timer1.Enabled = true;
    }
}
}

1 个答案:

答案 0 :(得分:1)

您当前遇到的问题是为set访问者提供一个正文,但为get提供一个正文(有关基本知识,请参见this post)。根据我的理解(和the documentation),在任何带有事件的访问器中都不需要正文(我也不认为也是允许的)。对于您的目标,最简单的解决方案是私下引发计时器事件(应为默认值),然后使用这些事件来调用自定义事件:

using System.Timers;
internal class DualTimer {

    #region Fields

    private Timer leftTimer;
    private Timer rightTimer;

    #endregion

    #region Events

    public event EventHandler LeftTick;
    public event EventHandler RightTick;

    #endregion

    #region Constructor(s)

    public DualTimer(int leftInterval, int rightInterval) {
        leftTimer = new Timer(leftInterval);
        rightTimer = new Timer(rightInterval);
        leftTimer.Elapsed += leftTimer_Elapsed;
        rightTimer.Elapsed += rightTimer_Elapsed;
    }

    #endregion

    #region Public Methods

    public void Start() {
        leftTimer.Start();
        rightTimer.Start();
    }
    public void Stop() {
        leftTimer.Stop();
        rightTimer.Stop();
    }

    #endregion

    #region Private Methods

    private void leftTimer_Elapsed(object sender, EventArgs e) {
        LeftTick(sender, e);
    }
    private void rightTimer_Elapsed(object sender, EventArgs e) {
        RightTick(sender, e);
    }

    #endregion

}

这将隐藏单个计时器的事件,因为它们是该类的私有对象。引发其过去的事件时,将分别引发您的左右对勾事件。可以很容易地扩展它以添加您的黄灯(顺便说一句,很好的类比)。此类的实现非常简单:

static DateTime startTime;
static void Main(string[] args) {
    DualTimer t = new DualTimer(100, 250);
    t.LeftTick += T_LeftTick;
    t.RightTick += T_RightTick;
    startTime = DateTime.Now;
    t.Start();
    Console.ReadKey();
    t.Stop();
}
private static void T_LeftTick(object sender, EventArgs e) {
    Console.WriteLine($"Right side tick. {DateTime.Now - startTime}");
}
private static void T_RightTick(object sender, EventArgs e) {
    Console.WriteLine($"Left side tick. {DateTime.Now - startTime}");
}

有关此问题的好书是MSDN教程,用于在您的类中实现事件。

  

以下过程描述了如何在类中实现事件。第一个过程实现一个没有关联数据的事件;它使用System.EventArgsSystem.EventHandler类作为事件数据和委托处理程序。第二个过程使用自定义数据实现事件;它为事件数据和事件委托处理程序定义了自定义类。

该教程非常详尽,并且具有很多有关事件的信息(有或没有数据)。请随时阅读以进一步学习。