- PR -

プログラムで起動したフォームのインスタンス開放について

1
投稿者投稿内容
reiko
ベテラン
会議室デビュー日: 2004/11/19
投稿数: 84
投稿日時: 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


じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-09-11 15:03
引用:

reikoさんの書き込み (2007-09-11 14:36) より:

clsFrm.Dispose() '←ここがインスタンス開放している「つもり」の所です。


"開放" ではなく "解放" という意味合いでよろしいでしょうか? とはいっても 「インスタンスを解放」 と言うと "参照の解放" などと意味を混同しがちです。 その行でやろうとしていることは 「(アンマネージ) リソースの破棄」 に当たります。

ところで Close しようとしているのは、そのイベントが起きる Form 自身ですから FormClosed イベントに書いてある内容は不要です。 ShowDialog メソッドで表示している場合は呼び出し元で Dispose メソッドを呼び出して (あるいは、Using ステートメントを使って) あげてください。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2007-09-11 15:03
引用:

現在メニューから1度起動されたDLLファイルをエクスプローラで
上書き等行うと、画面を閉じた後でも「使用中で上書き出来ません」の旨の
エラーになり、メニュー画面を閉じられるまでは上書きできない状態です。
(・・・これって、「インスタンスが残っている」という事であってますよね?)


あってません。

フォームの定義が exe にあろうと dll にあろうと変わりありません。

どうしても、該当の要件をお望みならば、別の AppDomain を作成して、dll のアセンブリはそこにロードする必要があります。

そして、AppDomain をアンロードするか、http://msdn2.microsoft.com/ja-jp/library/ms404279(VS.80).aspxの手順でシャドーコピーを有効にします。
(デフォルトのAppDomainはどちらもできない…はず)

但し、AppDomain をいくつも作るとデータの通信にはそれなりのルールが必要です。


_________________
囚人のジレンマな日々

[ メッセージ編集済み 編集者: 囚人 編集日時 2007-09-11 15:05 ]
reiko
ベテラン
会議室デビュー日: 2004/11/19
投稿数: 84
投稿日時: 2007-09-12 09:35
じゃんぬねっとさんへ

ご回答有難うございます。

"開放"・・・思いっきり全部間違ってましたね^^;
大変失礼しました(恥)

では、frm_FormClosed に書いてる
Disposeは意味がないんですね^^;

そうですよね・・・。
ShowDialogで開けたらフォームが起動済みかどうかも
チェックしなくて良いし色々ラクなのですが・・・。

ありがとうございました。



囚人さんへ

回答有難うございます。
そうですか・・・。
特別な処理をしなくてはいけない事だったのですね。
教えていただいたURLは、すぐにはついていけない内容なので
じっくり読んでみて、実際にやってみるか、諦めるか
検討してみようと思います。

ありがとうございました。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-09-12 12:26
引用:

じっくり読んでみて、実際にやってみるか、諦めるか
検討してみようと思います。



えっとですね、かなり面倒なんでやめた方がいいですよ (^^;

別ドメインを作った場合、「そっちで new したオブジェクト」を扱うのに、いちいち[
リモーティング」をしなければなりません。

例えば、別ドメインでフォームを new したとしても、そのフォームのメソッドやプロパティを直接呼び出すことができなかったりします。
reiko
ベテラン
会議室デビュー日: 2004/11/19
投稿数: 84
投稿日時: 2007-09-12 13:09
渋木宏明(ひどり)さんへ

ご回答有難うございます。

うわ。そうなんですか?なるほど・・・。
素直にやめとく事にします^^;

ありがとうございました♪
1

スキルアップ/キャリアアップ(JOB@IT)