2012-10-12 68 views
2

我有一个System.Timers.Timer,我发现在ElapsedEventHandler中有时会发生异常,但进程没有而是死亡,但执行ElapsedEventHandler的线程在异常时死亡发生。不好,因为我当时没有意识到这个例外。为什么不终止进程?如果ElapsedEventHandler发生异常,我怎样才能以最好的方式终止进程?当线程c发生异常时进程没有终止#

我试着用System.Threading.Timer类似,然后进程终止。 你能解释一下这个区别吗?下面

完整代码:

class Program 
{ 
    static public void DoBad() 
    { 
     Console.WriteLine("DoBad enter"); 
     string s = "hello"; 
     object o = s; 
     int i = (int)o; // Ops! Something unexpected happend here... Exception 
     Console.WriteLine("DoBad exit"); 
    } 

    static void DoIt1(object sender, System.Timers.ElapsedEventArgs e) 
    { 
     Console.WriteLine("\nDoIt1 enter"); 
     DoBad(); // Process is NOT terminated when excpetion occurs in DoBad, thread just dies quietly but process continues. Why is process not terminated? 
     Console.WriteLine("DoIt1 exit"); 
    } 

    static void Test1() 
    { 
     System.Timers.Timer t = new System.Timers.Timer(2000); 
     t.Elapsed += new System.Timers.ElapsedEventHandler(DoIt1); 
     t.Enabled = true; 
    } 

    static public void DoIt2(Object o) 
    { 
     Console.WriteLine("\nDoIt2 enter"); 
     DoBad(); // Process terminated when exception occurs in DoBad. 
     Console.WriteLine("DoIt2 exit"); 
    } 

    static void Test2()   
    { 
     System.Threading.Timer timer = new System.Threading.Timer(DoIt2, null, 0, 2000); 
    } 

    static void Main(string[] args) 
    { 
     Test1(); // Process NOT terminated when exception occurs in DoBad 
     // Test2(); // Process terminated when exception occurs in DoBad 

     // Why is process NOT terminated when running Test1 (but terminated when running Test2)? 
     // Want process to die. How to do it in best way? 

     Console.WriteLine("Main Sleep"); 
     System.Threading.Thread.Sleep(11000); 
     Console.WriteLine("Main Slept"); 
    } 
} 

/谢谢!

+1

System.Timers.Timer只是普通的讨厌的方式。它吞噬了Elapsed事件处理程序抛出的所有异常。无论是自己捕捉还是喜欢System.Threading.Timer –

回答

0

这是由设计完成的,因为你可以在这里看到:(system.timers.timer
在.NET Framework 2.0及更早版本中,定时器组件捕获并抑制由事件处理程序经过的事件引发的所有异常。此行为在未来的.NET Framework版本中可能会发生变化。

system.threading.timer不会这样做,所以异常被传出并终止进程。如果你想知道这个异常,那么你应该抓住它并记录下来。如果你希望所有的工作在主线程来完成
,您可以使用调用/ BeginInvoke的:

form1.Invoke((ThreadStart)delegate 
       { 
       //do something 
       }); 

或使用Windows.forms.timer(的WinForms)/ System.Windows.Threading.DispatcherTimer (WPF)