- - PR -
プログラムで起動したフォームのインスタンス開放について
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2007-09-11 14:36
いつもお世話になっております。
メニュー画面から起動したDLLプログラムの インスタンスを開放する方法を教えてください。 当システムは、ログオン&メニュー画面のみexeで作成し、 各処理画面はクラスライブラリで作成しています。 メニュー画面にはユーザの起動できるメニューがListBoxで表示されており、 リストをクリックした時に該当画面を起動します。 現在起動中の画面の情報はハッシュテーブルで管理するようにして、 既に起動済みの画面をもう一度呼び出そうとされた場合は、 起動済みの画面をアクティブにするようにしています。 フォームがクローズされた時にハッシュテーブルの情報を 消したいので、フォームクローズ処理は メニュー画面のところでプロシージャを作成し、 画面を起動するときにイベントハンドルを追加するという処理をしています。 現在メニューから1度起動されたDLLファイルをエクスプローラで 上書き等行うと、画面を閉じた後でも「使用中で上書き出来ません」の旨の エラーになり、メニュー画面を閉じられるまでは上書きできない状態です。 (・・・これって、「インスタンスが残っている」という事であってますよね?) 私としては、メニュー画面が閉じられなくても、該当DLLの画面が 閉じられたらそのファイルに関しては上書きOKになって欲しいのですが・・・。 ソースは以下の通りです。 ご指摘よろしくお願い致します。 <DLLで起動された各画面の初期起動フォームに関連付けるフォームクローズ処理> Private Sub frm_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Dim clsFrm As Form = sender htOpnForm.Remove(clsFrm.Name.ToString) clsFrm.Dispose() '←ここがインスタンス開放している「つもり」の所です。 ~~~~~~~~~~~~~~~~~ End Sub <DLL起動部分> Private Sub actDLL() Dim str As String = ListBox.SelectedValue Dim aryStr() As String aryStr = Split(str, ",") If aryStr(0) = DBNull.Value.ToString Then Exit Sub End If Try Dim myAsm As System.Reflection.[Assembly] = System.Reflection.[Assembly].LoadFrom _ (System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) & "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" & aryStr(0)) Dim myType As Type = myAsm.GetType(Mid(aryStr(0), 1, aryStr(0).Length - 4) & "." & aryStr(1)) Dim obj As Object = System.Activator.CreateInstance(myType) Dim myForm As Form = CType(obj, Form) ' *** 2重起動防止 *** If htOpnForm(aryStr(1)) Is Nothing Then myForm.StartPosition = FormStartPosition.Manual myForm.Location = New Point(0, 0) myForm.Show() htOpnForm.Add(aryStr(1), myForm) AddHandler myForm.FormClosed, AddressOf frm_FormClosed Else Dim myfrm As Form = Me.htOpnForm(aryStr(1)) myfrm.Activate() End If Catch ex As Exception MessageBox.Show("オープンエラー" & aryStr(1) & ControlChars.NewLine & ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) Me.Close() End Try End Sub | ||||
|
投稿日時: 2007-09-11 15:03
"開放" ではなく "解放" という意味合いでよろしいでしょうか? とはいっても 「インスタンスを解放」 と言うと "参照の解放" などと意味を混同しがちです。 その行でやろうとしていることは 「(アンマネージ) リソースの破棄」 に当たります。 ところで Close しようとしているのは、そのイベントが起きる Form 自身ですから FormClosed イベントに書いてある内容は不要です。 ShowDialog メソッドで表示している場合は呼び出し元で Dispose メソッドを呼び出して (あるいは、Using ステートメントを使って) あげてください。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||
|
投稿日時: 2007-09-11 15:03
あってません。 フォームの定義が exe にあろうと dll にあろうと変わりありません。 どうしても、該当の要件をお望みならば、別の AppDomain を作成して、dll のアセンブリはそこにロードする必要があります。 そして、AppDomain をアンロードするか、http://msdn2.microsoft.com/ja-jp/library/ms404279(VS.80).aspxの手順でシャドーコピーを有効にします。 (デフォルトのAppDomainはどちらもできない…はず) 但し、AppDomain をいくつも作るとデータの通信にはそれなりのルールが必要です。 _________________ 囚人のジレンマな日々 [ メッセージ編集済み 編集者: 囚人 編集日時 2007-09-11 15:05 ] | ||||
|
投稿日時: 2007-09-12 09:35
じゃんぬねっとさんへ
ご回答有難うございます。 "開放"・・・思いっきり全部間違ってましたね^^; 大変失礼しました(恥) では、frm_FormClosed に書いてる Disposeは意味がないんですね^^; そうですよね・・・。 ShowDialogで開けたらフォームが起動済みかどうかも チェックしなくて良いし色々ラクなのですが・・・。 ありがとうございました。 囚人さんへ 回答有難うございます。 そうですか・・・。 特別な処理をしなくてはいけない事だったのですね。 教えていただいたURLは、すぐにはついていけない内容なので じっくり読んでみて、実際にやってみるか、諦めるか 検討してみようと思います。 ありがとうございました。 | ||||
|
投稿日時: 2007-09-12 12:26
えっとですね、かなり面倒なんでやめた方がいいですよ (^^; 別ドメインを作った場合、「そっちで new したオブジェクト」を扱うのに、いちいち[ リモーティング」をしなければなりません。 例えば、別ドメインでフォームを new したとしても、そのフォームのメソッドやプロパティを直接呼び出すことができなかったりします。 | ||||
|
投稿日時: 2007-09-12 13:09
渋木宏明(ひどり)さんへ
ご回答有難うございます。 うわ。そうなんですか?なるほど・・・。 素直にやめとく事にします^^; ありがとうございました♪ |
1