System.Timers.Timer库中的Elapsed异常处理

时间:2012-09-25 12:03:57

标签: c# exception-handling timer

我想在我的WPF应用程序中处理发生的System.Timers.Timer经过的异常(在我的DLL库中)。但我无法做到这一点。它抛出我的DLL库,应用程序将崩溃... 有人知道我怎么解决这个问题吗?

这是我的代码:

public partial class MainWindow : Window
{
    MyClass _myClassInstance = null;

    public MainWindow()
    {
        InitializeComponent();

        try
        {
            _myClassInstance = new MyClass();
        } 
        catch(Exception ex)
        {
            //Here i would like to receive the exception
            //But it never goes in there
            MessageBox.Show(ex.Message);
        }
    }
}

public class MyClass
{
    private System.Timers.Timer _timer = null;

    public MyClass()
    {
        _timer = new Timer();
        _timer.Interval = 2000; //2 Seconds
        _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
        _timer.Start();
        ConnectTo();
    }

    void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        //If timer is elapsed I have to raise an exception
        throw new Exception("It's taking longer than expected. Progress cancelled!");
    }

    private void ConnectTo()
    {
        //Just an example implementation

        //Do something!!
        //Connect to SerialPort and wait for correct response

        //If connected than
        _timer.Stop();
    }
}

4 个答案:

答案 0 :(得分:3)

异常抛出在另一个线程上(根据您选择的Timing.Timer)。

在1个程序集中尝试这个:你也无法捕获它。它在DLL中并不重要。

您只能通过重新思考问题并选择其他解决方案来解决此问题。

答案 1 :(得分:1)

事件内发生异常。这是在另一个线程上运行的,因此它永远不会让它回到原始线程。

以不同方式做到这一点的两种可能性。

  1. 您的串口com库有某种超时功能(可能),只需使用它。
  2. 在单独的步骤中检查串行端口。如果你的时间用完了,就杀了那个线程。

    public class MyClass
    {
        private System.Timers.Timer _timer = null;
        private Thread t;
    
        public MyClass()
        {
            _timer = new Timer();
            _timer.Interval = 2000; //2 Seconds
            _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
            _timer.Start();
            t = new Thread(new ThreadStart(ConnectTo));
            t.Start();
            t.Join();
        }
    
        void _timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            //If timer is elapsed I have to raise an exception
            if (t != null)
                t.Abort();
        }
    
        private void ConnectTo()
        {
            //Just an example implementation
    
            //Do something!!
            //Connect to SerialPort and wait for correct response
    
            //If connected than
            _timer.Stop();
        }
    }
    

答案 2 :(得分:1)

作为替代方法,而不是尝试使用Exceptions控制应用程序流,您可以使用事件,例如。

public partial class MainWindow : Window
{
    MyClass _myClassInstance = null;

    public MainWindow()
    {
        InitializeComponent();
        _myClassInstance = new MyClass();
        _myClassInstance.TimedOut += delegate (object sender, EventArgs e) {
            ((MyClass)sender).CancelConnect();
            MessageBox.Show("Timeout!");
        };
        _myClassInstance.ConnectTo();
    }
}

...

public class MyClass
{
    Timer _timer = new Timer();

    public event EventHandler TimedOut;

    void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        OnTimedOut();
    }

    private void OnTimedOut()
    {
        var handler = TimedOut;
        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }

    public void ConnectTo(int timeout = 2000)
    {
        CancelConnect();
        _timer.Interval = timeout; // pass timeout in so it's flexible
        _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
        _timer.Start();
        // do connect stuff...
        _timer.Stop();
    }

    public void CancelConnect()
    {
        _timer.Stop();
        // cancel connect stuff...
    }
}

我认为您在MyClass的构造函数中进行了太多操作,因此我将其移至您ConnectTo直接调用的MainWindow

答案 3 :(得分:0)

不行:

MessageBox.Show(e.Message); doen's throw

public class MyClass
{
    private System.Timers.Timer _timer = null;
    private Thread t;

    public MyClass()
    {
        try
        {
        _timer = new System.Timers.Timer();
        _timer.Interval = 5000; //2 Seconds
        _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
        _timer.Start();
        t = new Thread(new ThreadStart(ConnectTo));
        t.Start();
        t.Join();
        }
        catch (Exception e)
        {

            MessageBox.Show(e.Message);
        }
    }

    void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        //If timer is elapsed I have to raise an exception
        if (t != null)
        {
            t.Abort();
        }
    }

    private void ConnectTo()
    {
        //Just an example implementation

        //Do something!!
        try
        {
            //Connect to SerialPort and wait for correct response
            using (SqlConnection _SC = new SqlConnection("aaaa"))
            {
                _SC.Open();
            }
        }
        catch (Exception)
        {

            throw;
        }
        finally
        {
            //If connected than
            _timer.Stop();
        }



    }
}