简体   繁体   English

如何订阅已提升的活动并一起打印?

[英]How do I subscribe to raised events and printing together?

I have been working on a program that has 3 classes of which 2 of the classes have timers that repeat at different intervals and once one "cycle" of the timer is done it raises an event with a string as return. 我一直在研究一个有3个类的程序,其中2个类具有以不同的间隔重复的定时器,并且一旦定时器的一个“循环”完成,它就会引发一个带有字符串作为返回的事件。 The 3rd class subscribes to the events from the other two timer classes and prints them to screen. 第3类从其他两个计时器类订阅事件并将它们打印到屏幕。 it works great! 它很棒!

But my issue is that it is printing them separately. 但我的问题是它是单独打印它们。 Lets say that the first timer class runs and then raises "hello" every 2 minutes and the other class "dog" every second and every time an event is raised it prints the raised event to console. 让我们说第一个计时器类运行,然后每2分钟引发一次“hello”,另一个类“dog”每秒发出一次,每次引发一个事件时它都会将引发的事件打印到控制台。 I would want it to instead print "hellodog" every second and store the value of the first timer(hello) in a private field or something so it still prints to screen even if the timer(the slower 2 minute timer) hasn't been fired. 我希望它反而每秒打印“hellodog”并将第一个计时器(你好)的值存储在一个私有字段或其他东西,所以它仍然打印到屏幕,即使计时器(较慢的2分钟计时器)还没有被解雇。 and when the 2 minute timer fires it updates the value to whatever the new one is and that new value get printed to screen until it fires again. 当2分钟计时器触发时,它将值更新为新的值,并将新值打印到屏幕,直到它再次触发。

If it is confusing I will gladly clarify. 如果令人困惑,我会很乐意澄清。 its kind of hard to explain. 它有点难以解释。

namespace Final
{
    public class Output
    {
        public static void Main()
        {
            var timer1 = new FormWithTimer();
            var timer2 = new FormWithTimer2();

            timer1.NewStringAvailable += new EventHandler<BaseClassThatCanRaiseEvent.StringEventArgs>(timer1_NewStringAvailable);

            timer2.NewStringAvailable += new EventHandler<BaseClassThatCanRaiseEvent.StringEventArgs>(timer2_NewStringAvailable);
            Console.ReadLine();
        }

        static void timer1_NewStringAvailable(object sender, BaseClassThatCanRaiseEvent.StringEventArgs e)
        {
            var theString = e.Value;

            //To something with 'theString' that came from timer 1
            Console.WriteLine(theString);
        }

        static void timer2_NewStringAvailable(object sender, BaseClassThatCanRaiseEvent.StringEventArgs e)
        {
            var theString2 = e.Value;

            //To something with 'theString2' that came from timer 2
            Console.WriteLine(theString2);
        }
    }

    public abstract class BaseClassThatCanRaiseEvent
    {
        public class StringEventArgs : EventArgs
        {
            public StringEventArgs(string value)
            {
                Value = value;
            }

            public string Value { get; private set; }
        }

        //The event itself that people can subscribe to
        public event EventHandler<StringEventArgs> NewStringAvailable;

        protected void RaiseEvent(string value)
        {
            var e = NewStringAvailable;
            if (e != null)
                e(this, new StringEventArgs(value));
        }
    }

    public partial class FormWithTimer : BaseClassThatCanRaiseEvent
    {
        Timer timer = new Timer();

        public FormWithTimer()
        {
            timer = new System.Timers.Timer(200000);

            timer.Elapsed += new ElapsedEventHandler(timer_Tick); // Everytime timer ticks, timer_Tick will be called
            timer.Interval = (200000);             // Timer will tick evert 10 seconds
            timer.Enabled = true;                       // Enable the timer
            timer.Start();                              // Start the timer
        }

        void timer_Tick(object sender, EventArgs e)
        {
            ... 
            RaiseEvent(gml.ToString());                    
        }
    }


    public partial class FormWithTimer2 : BaseClassThatCanRaiseEvent
    {
        Timer timer = new Timer();

        public FormWithTimer2()
        {
            timer = new System.Timers.Timer(1000);

            timer.Elapsed += new ElapsedEventHandler(timer_Tick2); // Everytime timer ticks, timer_Tick will be called
            timer.Interval = (1000);             // Timer will tick evert 10 seconds
            timer.Enabled = true;                       // Enable the timer
            timer.Start();                              // Start the timer
        }

        void timer_Tick2(object sender, EventArgs e)
        {
            ...
            RaiseEvent(aida.ToString());
        }
    }
}

Correct me if I misunderstand the question, but it sounds like you want to coordinate your response to the two timer events (print "hellodog"). 如果我误解了这个问题,请纠正我,但听起来你想要协调你对两个计时器事件的响应(打印“hellodog”)。

It seems to me that the easiest way to do this is to just use a single timer, and have the timer's event handler count the number of times the handler has been invoked to decide whether to take the once-per-second action, or also take the once-per-two-minutes action. 在我看来,最简单的方法是只使用一个计时器,并让计时器的事件处理程序计算调用处理程序的次数,以决定是否采取每秒一次的操作,或者采取每两分钟一次的行动。

Since the slow timer is an exact multiple of your fast timer, you would set just one timer that triggers every second, and also do the 2-minute action every 120 invocations of the 1 second timer (120 seconds = 2 minutes). 由于慢速计时器是快速计时器的精确倍数,因此您只需设置一个每秒触发的计时器,并且每1次计时器的120次调用(120秒= 2分钟)也会执行2分钟的操作。

I think I understand what you want and that is to synchronize the output of both timers. 我想我明白你想要什么,那就是同步两个计时器的输出。 I am afraid there is no way to do it other than to slog through it. 我担心除了通过它之外别无他法。 Set up a bunch of Boolean variables that track whether each event fired and whether the synchronized message was sent to the output. 设置一组布尔变量,用于跟踪是否触发了每个事件以及是否将同步消息发送到输出。

You can use the same event handler for both timers. 您可以为两个计时器使用相同的事件处理程序。 And construct the output by identifying the senders. 并通过识别发件人来构建输出。 (Didn't test the code for syntax errors.) (没有测试代码是否存在语法错误。)

private static string timer1Value = string.Empty;
private static string timer2Value = string.Empty;
private static FormWithTimer timer1;
private static FormWithTimer2 timer2;

public static void Main()
{
    timer1 = new FormWithTimer();
    timer2 = new FormWithTimer2();

    timer1.NewStringAvailable += new EventHandler<BaseClassThatCanRaiseEvent.StringEventArgs>(timer1_NewStringAvailable);

    timer2.NewStringAvailable += new EventHandler<BaseClassThatCanRaiseEvent.StringEventArgs>(timer1_NewStringAvailable);
    Console.ReadLine();
}


static void timer1_NewStringAvailable(object sender, BaseClassThatCanRaiseEvent.StringEventArgs e)
{
    if (sender == timer1)
    {
        timer1Value = e.Value.ToString();
    }
    else if (sender == timer2)
    {
        timer2Value = e.Value.ToString();
    }

    if (timer1Value != String.Empty && timer2Value != String.Empty)
    {
        Console.WriteLine(timer1Value + timer2Value); 
        // Do the string concatenation as you want.
    }

This should do what you want. 这应该做你想要的。

    public static void Main()
    {
        var timer1 = new FormWithTimer();
        var timer2 = new FormWithTimer2();

        var value1 = "";
        var value2 = "";

        Action writeValues = () => Console.WriteLine(value1 + value2);

        timer1.NewStringAvailable += (s, e) =>
        {
            value1 = e.Value;
            writeValues();
        };

        timer2.NewStringAvailable += (s, e) =>
        {
            value2 = e.Value;
            writeValues();
        };

        Console.ReadLine();
    }

Let me know if this is right. 如果这是对的,请告诉我。 Cheers. 干杯。

The second (quicker) timer should be the only one to print. 第二个(更快)计时器应该是唯一打印的计时器。 The first (slower) timer should only update a string which the second timer will use. 第一个(较慢的)计时器应该只更新第二个计时器将使用的字符串。

In the 'Output' class (you can put it before Main): 在“输出”类中(您可以将它放在Main之前):

string string1;

and then: 然后:

static void timer1_NewStringAvailable(object sender, BaseClassThatCanRaiseEvent.StringEventArgs e)
{
    string1 = e.Value;
}

static void timer2_NewStringAvailable(object sender, BaseClassThatCanRaiseEvent.StringEventArgs e)
{
    var theString2 = e.Value;

    //To something with 'theString2' that came from timer 2
    Console.WriteLine(string1 + theString2);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM