如何在C#.NET中进行事件驱动编程?

问题描述:

如何在事件驱动程序中执行主流程时暂停,只要事件引发并处理,直到事件处理程序结束?如何在C#.NET中进行事件驱动编程?

我创建了下面的程序

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Timers; 

namespace EventTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Timer t = new Timer(2000); 
      t.Enabled = true; 
      t.Elapsed += new ElapsedEventHandler(TimerHandler); 
      for (int i = 0; i < 10000; i++) 
      { 
       for (int j = 0; j < 100000000; j++) ; 
       Console.WriteLine(i); 
      } 
     } 
     public static void TimerHandler(object source, EventArgs e) 
     { 
      Console.WriteLine("Event started"); 
      for (int i = 0; i < 5; i++) 
      { 
       for (int j = 0; j < 100000000; j++) ; 
       Console.WriteLine("Event "+i); 
      } 
      Console.WriteLine("Event finished"); 
     } 

    } 
} 

主要方法是应该打印序列号,和一个事件被每2秒烧制。在事件处理期间,程序应该打印“事件已启动”,“事件1”至“事件5”,然后“事件已完成”,然后返回。

我预期的Main()流停止而TimerHandler()被调用,但是我的输出显示,主()和TimerHandler()都同时

0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
Event started 
12 
Event 0 
13 
Event 1 
14 
Event 2 
15 
Event 3 
16 
Event 4 
Event finished 
17 
18 
19 
20 
21 
22 
23 
Event started 
24 
Event 0 
25 
Event 1 
26 
Event 2 
27 
Event 3 
28 
Event 4 
Event finished 
29 
30 
31 
32 
33 

运行是否有可能使主( )方法在事件处理时停止?

+1

另外,小费,如果你想要做的就是让程序暂停几毫秒,以便您的测试程序不会运行并完成太快,您可以使用Thread.Sleep(10);睡10毫秒,而不是你的内在循环。 – 2010-07-07 09:56:02

您使用System.Timers.Timer,其处理蜱在后台线程,通常使用线程池。

这样,是的,它会同时与你的主代码的其余部分运行。

关于你的第二个问题,有可能得到主停下来,我需要知道预期的行为是什么。

如果你想在TimerHandler整个蜱一起运行,暂停主而它这样做,简单的锁就足够了:

namespace EventTest 
{ 
    class Program 
    { 
     static object _Lock = new object(); 

     static void Main(string[] args) 
     { 
      Timer t = new Timer(2000); 
      t.Enabled = true; 
      t.Elapsed += new ElapsedEventHandler(TimerHandler); 
      for (int i = 0; i < 10000; i++) 
      { 
       for (int j = 0; j < 100000000; j++) ; 
       lock (_Lock) 
        Console.WriteLine(i); 
      } 
     } 
     public static void TimerHandler(object source, EventArgs e) 
     { 
      lock (_Lock) 
      { 
       Console.WriteLine("Event started"); 
       for (int i = 0; i < 5; i++) 
       { 
        for (int j = 0; j < 100000000; j++) ; 
        Console.WriteLine("Event "+i); 
       } 
       Console.WriteLine("Event finished"); 
      } 
     } 
    } 
} 
+0

有没有什么办法可以在处理程序运行时停止Main()方法? – 2010-07-07 09:54:09

+0

编辑我的答案。 – 2010-07-07 09:54:48

+1

@Lasse - 纠正我,如果我错了,但用这种方法不会最终出现竞争条件,这只能工作,因为处理程序抢在Main()之前的锁?用Manual/AutoResetEvent你不会更好吗? – slugster 2010-07-07 10:04:53