「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 と同様、使いどころには十分な注意を払う必要がある命令です。