VB.NET質問スレ

このエントリーをはてなブックマークに追加
37デフォルトの名無しさん
>>23
>エクセルを起動したアプリを終了してもエクセルのプロセスが消えない問題は 
>VB6の時は確かにあった。 

VB6でのこの問題はClose/Quit操作漏れの他に、
End命令や捕捉されていない例外で終了した場合にCOMオブジェクト破棄がなされないことにある。
この場合COMオブジェクトがアウトプロセスサーバーの場合はそのプロセスが残る。
一方、全フォームがUnloadか閉じるで終了した場合は後処理でオブジェクトの破棄はなされる。

COMへの参照をグローバルやstatic変数に置くとNothingを設定しない限り
終了時まで参照が残るため、Endで終了した場合は後処理が省かれプロセスが残ってしまう。
さらにFormの暗黙のインスタンスの問題がある。Formで暗黙のインスタンスを使った場合、
そのFormのインスタンスはUnload(閉じるを含む)したとしても、プロセスの終了まで破棄されない。
ただしUnload(閉じるを含む) とSet Form1 = Nothingの両方の操作を行った場合は破棄される。
このためFormのフィールドにCOMの参照を置いた場合もグローバルやstatic変数に置くのと
同じ問題が発生する。あとケースとしてはまれだが循環参照があった場合も同様。
38デフォルトの名無しさん:2007/09/07(金) 12:05:42
>>37 続き

VB.NETの場合はEnvironment.Exitで終了しても未補足の例外で異常終了した場合も
オブジェクトの終了処理はなされるので問題はおきにくい。
例外はCLR自体が~C操作やOS側の例外での終了した場合。

Formの暗黙のインスタンスはVB6と似た動きをするので早期に参照を破棄したい場合は
同様の注意が必要になる。
暗黙のインスタンスではForm1のメソッドにアクセスする時に、
Form1が初期状態(Nothing)または既にDispose(Close)された状態であれば
新規にForm1のインスタンスを生成してForm1に設定する。
VB6と違ってUnload(Dispose)後の再利用はしないが、
参照が破棄されるのは次のForm1を新たに操作し始めたタイミングになる。
Dispose後速やかにGCの対象にするためにはSet Form1 = Nothingの操作が必要になる。