7

現在スローされている例外を取得する方法はありますか (存在する場合)?

コードの量を減らして、タスクの再利用を次のように適用したいと思います。

Exception thrownException = null;
try {
    // some code with 3rd party classes, which can throw unexpected exceptions
}
catch( Exception exc ) {
    thrownException = exc;
    LogException( exc );
}
finally {
    if ( null == thrownException ) {
        // some code
    }
    else {
        // some code
    }
}

それを次のコードに置き換えます。

using( ExceptionHelper.LogException() ) {
    // some code with 3rd party classes, which can throw unexpected exceptions
}
using( new ExceptionHelper { ExceptionAction = ()=> /*some cleaning code*/ } ) {
    // some code with 3rd party classes, which can throw unexpected exceptions
}

public class ExceptiohHelper : IDisposable {
    public static ExceptionHelper LogException() {
        return new ExceptionHelper();
    }

    public Action SuccessfulAction {get; set;}
    public Action ExceptionAction {get; set;}

    public void Dispose() {
        Action action;
        Exception thrownException = TheMethodIDontKnow();
        if ( null != thrownException ) {
            LogException( thrownException );
            action = this.ExceptionAction;
        }
        else {
            action = this.SuccessfulAction;
        }

        if ( null != action ) {
            action();
        }
    }
}

このシナリオは可能ですか?

ありがとう

4

3 に答える 3

11

アイデアは、catch ブロックで例外を処理するということです...

つまり、Exception は参照型なので、いつでも try スコープの外で Exception 変数を宣言できます...

Exception dontDoThis;
try
{
    foo.DoSomething();
}
catch(Exception e)
{
    dontDoThis = e;
}
finally
{
    // use dontDoThis...
}
于 2010-01-14T08:43:05.523 に答える
5

次のことについてどう思いますか。問題を「最後の例外を取得する方法」と見なす代わりに、「さらに制御を加えてコードを実行するにはどうすればよいですか?」に変更するとどうなりますか?

例:ExceptionHelperの代わりに、ActionRunnerを使用できます。

public class ActionRunner
{
    public Action AttemptAction { get; set; }
    public Action SuccessfulAction { get; set; }
    public Action ExceptionAction { get; set; }

    public void RunAction()
    {
        try
        {
            AttemptAction();
            SuccessfulAction();
        }
        catch (Exception ex)
        {
            LogException(ex);
            ExceptionAction();
        }
    }

    private void LogException(Exception thrownException) { /* log here... */ }
}

AttemptActionのみが呼び出し間で変化すると仮定すると、少なくとも、SuccessfulActionとExceptionActionをある程度再利用できます。

var actionRunner = new ActionRunner
{
    AttemptAction = () =>
    {
        Console.WriteLine("Going to throw...");
        throw new Exception("Just throwing");
    },
    ExceptionAction = () => Console.WriteLine("ExceptionAction"),
    SuccessfulAction = () => Console.WriteLine("SuccessfulAction"),
};
actionRunner.RunAction();

actionRunner.AttemptAction = () => Console.WriteLine("Running some other code...");
actionRunner.RunAction();
于 2010-01-14T10:46:56.477 に答える
3

予期しない例外をキャッチしたい場合は、UnhandledExceptionを処理する必要があります。(単にログに記録するのではなく) 処理する予定の下位レベルでのみ例外をキャッチする必要があります。それ以外の場合は、例外をバブルアップさせて上位レベルでキャッチするか、前述の UnhandledException メソッドで説明したようにします。

于 2010-01-14T08:47:37.760 に答える