1

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

4 に答える 4

3

例外は別のスレッドでスローされます (Timing.Timer の選択に従って)。

1つのアセンブリ内でこれを試してください:どちらもキャッチできません。DLL 内にあるかどうかは問題ではありません。

問題を再考し、別の解決策を選択することによってのみ、これを解決できます。

于 2012-09-25T12:07:20.997 に答える
1

例外はイベント内で発生しています。これは別のスレッドで実行されるため、元のスレッドに戻ることはありません。

これを別の方法で行うには2つの可能性があります。

  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();
        }
    }
    
于 2012-09-25T12:09:01.830 に答える
1

別のアプローチとして、例外を使用してアプリケーション フローを制御しようとするのではなく、代わりにイベントを使用できます。

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のでConnectToMainWindow.

于 2012-09-25T12:23:18.607 に答える