为什么这个事件会发生两次?

时间:2012-04-07 01:33:47

标签: c# multithreading events

我正在学习Daniel M. Solis的Book Illustrated C#2010中的C#事件,并且我正在尝试给出关于VS 2010中的事件的示例。出于某种原因,我得到了两次事件消息,但对于我的生活我无法弄清楚为什么。这是代码:

using System;
using System.Text;
using System.Threading;

namespace ConsoleApplication3
{
    internal class MyTimerClass
    {
        public event EventHandler<MyTCEventArgs> Elapsed;

        public void OnOneSecond(object source, EventArgs args)
        {
            if (Elapsed != null)
            {
                MyTCEventArgs mtcea = new MyTCEventArgs("Message from OnOneSecond");
                Elapsed(source, mtcea);
            }
        }

        //-----------------
        private System.Timers.Timer MyPrivateTimer;

        public MyTimerClass()
        {
            MyPrivateTimer = new System.Timers.Timer();

            MyPrivateTimer.Elapsed += OnOneSecond;

            MyPrivateTimer.Interval = 1000;

            MyPrivateTimer.Enabled = true;
        }
    }

    internal class ClassA
    {
        public void TimerHandlerA(object source, MyTCEventArgs args)
        {
            Console.WriteLine("Class A Message: {0}", args.Message);
        }
    }

    internal class ClassB
    {
        public static void TimerHandlerB(object source, MyTCEventArgs args)
        {
            Console.WriteLine("Class B Message: {0}", args.Message);
        }
    }

    internal class MyTCEventArgs : EventArgs
    {
        public string Message;

        public MyTCEventArgs(string s)
        {
            Message = s;
        }
    }

    internal class Program
    {
        private static void Main(string[] args)
        {
            ClassA ca = new ClassA();
            MyTimerClass mc = new MyTimerClass();

            mc.Elapsed += new EventHandler<MyTCEventArgs>(ca.TimerHandlerA);
            mc.Elapsed += new EventHandler<MyTCEventArgs>(ClassB.TimerHandlerB);

            Thread.Sleep(2250);
        }
    }
}

结果是以下消息: A类消息:来自OnOneSecond的消息 B类消息:来自OnOneSecond的消息 A类消息:来自OnOneSecond的消息 B类消息:来自OnOneSecond的消息

为什么会发生两次?另外,当我删除Thread.Sleep行时,根本就没有任何事情发生。这也让我感到困惑。

1 个答案:

答案 0 :(得分:4)

您的计时器正在另一个线程上运行,因此调用Sleep()时不会阻止它。它的间隔为1000,您可以在2250睡觉。因此,Tick事件将在此期间被提升两次,这就是您所看到的。

如果你移除睡眠没有任何反应的原因是你的程序在Tick事件被触发之前退出。请记住,该事件每1000 ms引发一次,并且所需的时间比程序退出的时间少得多。