投稿者 魔界の仮面弁士  (社会人) 投稿日時 2017/12/11 15:38:24
何にせよ、外部からの強制終了には出来る限り頼らないようにしましょう。

たとえば BackgroundWorker で処理さえているのであれば、
CancelAsync メソッド → CancellationPending プロパティで中断通知としますし、
Task を使っているのであれば、CancellationTokenSource を利用するといった手があります。
http://www.atmarkit.co.jp/fdotnet/dotnettips/437bgwcancel/bgwcancel.html
http://note.websmil.com/vb/スレッド・タスク/vb-net-taskクラスの処理キャンセル



で、Task の中断という話とは別になりますが――たとえば System.Windows.Forms.Form の場合、
FormClosing / FormClosed イベントの引数 e.Reason を見ることで、
終了理由をある程度推し量れるかと思います。
しかしこれとて、強制終了時には通知すらされません。
https://dobon.net/vb/dotnet/form/unloadmode.html
https://msdn.microsoft.com/ja-jp/library/system.windows.forms.closereason%28vs.90%29.aspx

このとき、e.Reason に渡される値の一つに TaskManagerClosing というものがありますが、
これは、外部プロセスからの WM_CLOSE メッセージの受信を意味するものであり、
必ずしもタスクマネージャーからの終了を指し示すとは限らないのでご注意を。
https://social.msdn.microsoft.com/Forums/ja-JP/bca1296d-c35f-49d0-8d61-fbf0d45d8ee3/formclosing



> ちなみにですが、最後の「Eccelで~」とはVBAのことですか?
Eccel ではなく、Excel ですね。

強制終了によって整合性に問題が生じるという話は、
開発言語が VBA だろうと MFC だろうと何だろうと、根本的には同じことです。


一応、『ファイルの入出力最中に停止しても、ファイルシステムが破損しないこと』は
OS レベルで保証されていますが、書き込み内容が中断されることについては避けられません。

それに、いくら Windows が、OS レベルでのファイルシステムの一貫性を保証していたとしても、
書き込み中に電源が切られたりすれば、ファイルシステムの一貫性すら保証されませんよね。

そこで Windows は、強制的に電源が切られた後の次回起動時に、不整合の検査のため
スキャンディスク等によるファイルシステムのチェックと修復を試みる仕組みが用意されています。

Excel というアプリも同様です。前回終了時に正しく終了されていなかったことを
検知した場合には、自動退避しておいた一時ファイル等の情報を読み取った上で、
それらをユーザーに提示して、どのデータを残すのか目視チェックを促すように設計されています。

また、ここでは話を分かりやすくするためにファイル操作を例として挙げていますが、
実際に生じる問題としては、ネットワーク通信やオブジェクトハンドルなど多岐に渡ります。


> フラグをチェックして処理を中断する場合でも、同じようなデータ欠落を想像してしまうのですが、どうでしょうか…?
通常の終了時であれば、終了通知なり Finally なりによって、
後始末するための猶予が与えられますが、強制終了ではそうも行きませんね。

強制終了に備える方法の一案としては、作業状態を中断できる機能を設けておき、
次回起動時にはその状態から復帰できるようにしておくといった手段があります。

たとえば作業中の処理を、ファイルなりクラウドなりに随時残しておき、
次回起動時にはそれを読み取ることで、前回の処理が中断したのか
正常終了したのかを判断し、必要なら前回の続きから再開させるわけです。

逆に言えば、前回の処理結果を保持するような仕組みが無いのなら、
今までの作業内容が単に失われるのみであるとも言えます。
この辺のさじ加減は、アプリケーション要件によるところですね。
(たとえば、電卓アプリを強制終了したときに、前回の計算式を残しておく
 必要があるのか、最初から打ち直してもらって構わないのか、といった具合に)

とはいえ、強制終了が悪手であることは変わりません。
たとえばアンマネージリソース(オブジェクトハンドルなど)を使っていた場合、
それらを処分することなく強制終了してしまうと、その分のリソースが解放漏れに
なってしまい、OS を再起動するまで再利用できない状態に陥る可能性がありえます。

※リソースリークは、強制終了時にのみ起こるわけではありません。
 確保したリソースが処分される前に、新たなリソースが次々と
 確保するようなシステムであれば、それもリークと言えます。