[VB.NET] Application.Exit の使用は期待を裏切る

2013年12月19日

 「End の使用は信頼を裏切る」(http://ooltcloud.sakura.ne.jp/blog/201312/article_11223915.html)の続きエントリーです。

 アプリケーションをコードから終了させたいとき、End(=Environment.Exit) を使わないとすると、どうすればいいのか?という問いに対して、WinForm の場合だと、Application.Exit を使えばよいといわれることがあります。
 ということなので、Application.Exit の動きを確認してみます。

 まず、こんなコードを用意してみます。

Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Dim ret1 = MsgBox("終了しますか?", MsgBoxStyle.OkCancel)

        If ret1 = MsgBoxResult.Ok Then
            Debug.Print("終了しました")
            Application.Exit()
            ' これ以下は実行しないはず?
        End If


        Dim ret2 = MsgBox("処理Aを実行します。よろしいですか?", MsgBoxStyle.OkCancel)

        If ret2 = MsgBoxResult.Ok Then
            Debug.Print("処理Aを実行")
            Dim f = New Form2
            f.ShowDialog()
        Else
            Debug.Print("処理Aを中止")
        End If

    End Sub

End Class

 途中に出てくる form2 ではこんな処理を書いておきます。

Public Class Form2

    Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Debug.Print("1 Form2_Load")
    End Sub

    Private Sub Form2_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        Debug.Print("2 Form2_FormClosing")
    End Sub

    Private Sub Form2_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        Debug.Print("3 Form2_FormClosed")
    End Sub

End Class

 最初の「終了しますか?」の MsgBox で「OK」を選択します。
 すると Application.Exit が実行されるので、そこで終了…となるかというとそうではありません。実行結果は以下のようになります。

終了しました
処理Aを実行
1 Form2_Load

 一行目の「終了しました」は期待通りの動作です。そして、2つ目の MsgBox は表示されません。これも期待通りです。
 しかし実行結果の二行目には「処理Aを実行」が出力されています・・・

 まとめると、Application.Exit を実行した場合、以下のことが起こります。

  • 今表示中のウインドウはすべて閉じる (閉じるボタンが押されるのと等価)
  • これから表示しようとするウインドウは表示しない。

 これで最終的にはすべてのウインドウが閉じられるので、アプリケーションも終了・・・となるわけですが、その途中の処理は一切キャンセルされません。この点には注意が必要です。

 そのほかにも以下の点に注意が必要です。

  • 表示しなかった MsgBox の戻り値は MsgBoxResult.Ok が戻ります。Cancel ではなく Ok が戻る点に注意が必要です。
  • 表示しようとした Form2 は、Load イベントは処理されますが、Close系 のイベントは発生しません。(実行結果の3行目)
  • FormClosing イベントの e.Cancel を True で戻すと Application の終了を抑止できてしまいます。(例示のコードにはこの処理は書いていません)

 つまり、Application.Exit は都合のいいところで中断できる便利な命令ではありません。Application.Exit を実行するとその場で中断してもらえると思っていると、期待に反する動きをしてしまうことがあります。End と同様、使いどころには十分な注意を払う必要がある命令です。






カテゴリー: Program, VB.NET

Follow comments via the RSS Feed | Leave a comment | Trackback URL

コメントを投稿する

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


«   »
 
Powered by Wordpress and MySQL. Theme by Shlomi Noach, openark.org