C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

TryのFinallyの意義

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■93490 / inTopicNo.1)  TryのFinallyの意義
  
□投稿者/ ハリー (1回)-(2019/12/15(Sun) 12:47:07)

分類:[.NET 全般] 

TryのFinallyの意義について教えてください

Finallyはエラーがあってもなくても実行するコードなので
以下の二つのコードは等価な処理を行うと思います
それならFinallyというものの存在意義がよく分からないのですが
どういう時に使えば良いのでしょうか?






コード1

Dim aaa As Integer

Try
 
    aaa += 1

Catch ex As Exception

    aaa += 2

Finally
 
    aaa += 3

End  Try







コード2

Dim aaa As Integer

Try
 
    aaa += 1

Catch ex As Exception

    aaa += 2

End  Try


    aaa += 3


引用返信 編集キー/
■93491 / inTopicNo.2)  Re[1]: TryのFinallyの意義
□投稿者/ Hongliang (938回)-(2019/12/15(Sun) 12:52:29)
2019/12/15(Sun) 12:53:11 編集(投稿者)
Catchしたときに例外を再Throwしたり関数から抜ける時などでも実行してくれます。
// Catchしたときも実行を継続するケースというのはどちらかといえば少ないんではないかと。

Try
    Hoge()
Catch (HogeException ex)
    Throw New InvalidOperationException("Hogeに失敗しました", ex)
Finally
    Cleanup()
End Try

Try
    Return Hoge()
Catch (HogeException ex)
    Log.Debug($"Hogeに失敗: {ex}")
    Return Nothing
Finally
    Cleanup()
End Try

引用返信 編集キー/
■93494 / inTopicNo.3)  Re[1]: TryのFinallyの意義
□投稿者/ WebSurfer (1990回)-(2019/12/15(Sun) 14:21:59)
No93490 (ハリー さん) に返信

> それならFinallyというものの存在意義がよく分からないのですが
> どういう時に使えば良いのでしょうか?

Exception を catch して発生した例外をなかったことにすることは普通やらないのです。
ログを取って再スローするということはあると思いますが。

質問にあったようねコードを書くことはまずない(Exception は catch しない。catch し
ても再スローする)ので、例外が発生するとアプリケーションが停止します。

そうなるとマズイのは、例えば SQL Server に接続プールを利用して接続しているような
場合で SQL Server の障害などでれいがーがスローされると、接続プールに接続を戻さな
いままアプリケーションは終了してしまい、リソースリークとなってしまいます。

FInally で接続をプールに戻すコードを書けば、例外が発生しても Finally のコードは実
行されるのでリソースリークは防ぐことができます。

VB.NET では Visual Studio のエディタで Try とタイプすると Catch ex As Exception
が自動的に追加されますが、それをそのままにしておくのは問題が多すぎだと思います。


本題とはちょっと外れますが、例外処置について、自分的に一般的と思うことを書いてお
きます。参考になれば幸いです。

(1) 予測可能で正しい業務フローに戻すことができる「業務エラー」(例:ユーザーの
  入力間違い)と、予測できないもしくは予測はできても何の対応もできない「例外」
  (例:DB サーバーダウン)を区別して対処。

(2) 「例外」はランタイムに拾わせてアプリケーションを停止させる。

(3) よほどのことがない限り try-catch は書かない。

(4) キャッチせざるを得ない場合でも Execption はキャッチしない。

(5) 間違って補足してしまった例外は throw する。(注:catch ブロックでキャッチした
  例外を throw するとスタックトレースが途切れるので単に throw と書く)

(6) ユーザーへの通知が必要なら、集約的例外処置を利用する。

詳しくは以下の記事を見てください。

NETの例外処理 Part.1
https://blogs.msdn.microsoft.com/nakama/2008/12/29/net-part-1/

.NETの例外処理 Part.2
https://blogs.msdn.microsoft.com/nakama/2009/01/02/net-part-2/

あと、.NET 4 からは破損状態例外は catch できなくなっているそうですが、「それでも
Catch (Exception e) を使用するのはよくない」ということについては以下の記事を見て
ください。

破損状態例外を処理する
https://docs.microsoft.com/ja-jp/archive/msdn-magazine/2009/february/clr-inside-out-handling-corrupted-state-exceptions

引用返信 編集キー/
■93512 / inTopicNo.4)  Re[2]: TryのFinallyの意義
□投稿者/ 中博俊 (4回)-(2019/12/16(Mon) 18:24:30)
別にfinallyじゃないといけないわけじゃないというなら、そう書かなくてもいいけど、

try{
Icon="kurukuru"
}finally{
Icon="arror"
}

みたいなどうしても戻したい、どうしても捨てたいみたいなものがあれば使わないとだめだと思いません?
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ