3

私は3つのクラスを持つプログラムに取り組んでおり、そのうち2つのクラスには異なる間隔で繰り返されるタイマーがあり、タイマーの1つの「サイクル」が完了すると、文字列を返すイベントが発生します。3 番目のクラスは、他の 2 つのタイマー クラスからのイベントをサブスクライブし、それらを画面に出力します。それはうまくいきます!

しかし、私の問題は、それらを別々に印刷していることです。最初のタイマー クラスが実行され、2 分ごとに "hello" が発生し、もう 1 つのクラス "dog" が 1 秒ごとに発生し、イベントが発生するたびに、発生したイベントがコンソールに出力されるとします。代わりに、毎秒「hellodog」を出力し、最初のタイマー (hello) の値をプライベート フィールドなどに保存して、タイマー (遅い 2 分のタイマー) が実行されていなくても画面に出力するようにしたいと思います。解雇した。2分のタイマーが起動すると、値が新しいものに更新され、その新しい値が再び起動するまで画面に出力されます。

混乱している場合は、喜んで明確にします。説明するのは難しいです。

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());
        }
    }
}
4

5 に答える 5

1

両方のタイマーに同じイベントハンドラーを使用できます。そして、送信者を特定して出力を作成します。(構文エラーについてコードをテストしませんでした。)

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.
    }
于 2011-09-11T03:15:47.367 に答える
1

2 番目の (速い) タイマーだけを印刷する必要があります。最初の (遅い) タイマーは、2 番目のタイマーが使用する文字列のみを更新する必要があります。

「出力」クラス (メインの前に置くことができます):

string string1;

その後:

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);
}
于 2011-09-11T21:52:00.977 に答える
1

私はあなたが何を望んでいるかを理解していると思います.それは両方のタイマーの出力を同期させることです. 残念ながら、それを突き抜ける以外に方法はありません。各イベントが発生したかどうか、および同期されたメッセージが出力に送信されたかどうかを追跡する一連のブール変数を設定します。

于 2011-09-11T00:16:39.750 に答える
1

これはあなたが望むことをするはずです。

    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();
    }

これが正しいかどうか教えてください。乾杯。

于 2011-09-11T08:11:37.797 に答える
1

質問を誤解している場合は訂正してください。ただし、2 つのタイマー イベント (print "hellodog") への応答を調整したいようです。

これを行う最も簡単な方法は、単一のタイマーを使用し、タイマーのイベントハンドラーにハンドラーが呼び出された回数をカウントさせて、1秒に1回のアクションを実行するかどうかを決定することです。 2 分に 1 回のアクションを実行します。

低速タイマーは高速タイマーの正確な倍数であるため、1 秒ごとにトリガーするタイマーを 1 つだけ設定し、1 秒タイマーを 120 回呼び出すたびに 2 分間のアクションを実行します (120 秒 = 2 分)。

于 2011-09-11T00:13:13.713 に答える