- PR -

起動中アプリケーションに対しての処理について

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

なちゃさんの書き込み (2005-12-04 16:23) より:

mutexのcloseが後ろにあっても駄目なんですかね?
※念のため、私は「後ろにCloseがあるから不要なのでは?」と思ったわけです。


Ensuring that only a single instance of a .NET application is running に、

引用:

But the JIT compiler sees that the mutex is only used near the beginning of the program, and may discard it prematurely when memory is needed for something else! This only happens with rather large, complex programs and was a real puzzle to me.


というくだりがあります。
しかし、例文には Close がないですね...
IDE 上で実行した場合は起きにくいというのもちょっと謎ですが...

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-12-04 22:55
引用:

Hongliangさんの書き込み (2005-12-04 15:24) より:

GC.KeepAliveは、
事前ではなく事後に呼び出すメソッドです。非常に奇妙な印象を受けますが。


この組み合わせを検索したところ、本家でこんな記事を発見しました。

  二重起動を禁止する方法について

これもおかしいですね。

私の記事は 1 年ほど前に書いた記事で、本家の記事の最終更新日は、2005年6月30日...
うーん、ま、まさかね... (^^;)

# エントリ ポイントには珍しい Protected 修飾子...
# その他諸々を見て、考えてはいけないことを考えてしまいました。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2005-12-04 23:06
引用:

じゃんぬねっとさんの書き込み (2005-12-04 22:55) より:
二重起動を禁止する方法について

これもおかしいですね。


わ、笑ってしまいました…

それはさておき、
引用:

But the JIT compiler sees that the mutex is only used near the beginning of the program, and may discard it prematurely when memory is needed for something else! This only happens with rather large, complex programs and was a real puzzle to me.


ですが、要するに最初でしかMutexへの参照を行っていないため、JITコンパイラが
勝手にローカルの参照を削除してしまい(厳密な表現はよく分かりませんが)、
GCの対象になってしまうので、KeepAliveを最後に入れる必要があるということかなと
思いました。
なんで、CloseがあればそれがKeepAliveの代わりを果たしている(この時点でメソッド
呼び出しのために直接参照が必要になるのだから、GCの対象にしてはならないのは
明らか)ので、特にKeepAliveで明示する必要はないと。
※ていうか、これで問題が起こるのならかなりおかしいバグということに…

状況によって問題が起こったり起こらなかったりするというのは、JITの最適化やら何やらで動作が変わってしまうからでしょう。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-12-04 23:30
引用:

なちゃさんの書き込み (2005-12-04 23:06) より:

わ、笑ってしまいました…


これ... 私から報告しときますね... (^-^A)

引用:

ですが、要するに最初でしかMutexへの参照を行っていないため、JITコンパイラが
勝手にローカルの参照を削除してしまい(厳密な表現はよく分かりませんが)、
GCの対象になってしまうので、KeepAliveを最後に入れる必要があるということかなと
思いました。


はい、GC の対象となることがあるようで、それを防ぐためのものですね。

引用:

なんで、CloseがあればそれがKeepAliveの代わりを果たしている(この時点でメソッド
呼び出しのために直接参照が必要になるのだから、GCの対象にしてはならないのは
明らか)ので、特にKeepAliveで明示する必要はないと。


Close メソッドではダメだったということなのかどうかは判りませんが、
安全性などから採用しているのかもしれません。(Google の検索結果を見る限り)

引用:

状況によって問題が起こったり起こらなかったりするというのは、JITの最適化やら何やらで動作が変わってしまうからでしょう。


IDE 上ではなく実行ファイルから実行した方が起こりやすいというのも、そういうことなのでしょうね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-12-05 06:19
引用:

ダッチさんの書き込み (2005-12-04 14:54) より:

' 新規作成処理
mainWindow.AddWindow()
を実行しても一瞬でウィンドウが閉じてしまいます。
おそらくApplication.Run(New MainWindow)
で生成した MainWindow のインスタンスに対して
処理を行っていないからではないかと思います。
そのためメッセージループされていないのではないでしょうか。



で、解決したの?
ってか、原因はわかっているんだから、解決したんだよね?

(メソッドに渡すところで new しているから、メソッドに渡すところの外で捕まえられないんだから、作ってから渡せばいいよね?)
___________________________________________________________________
□ written by Jitta on 2005/12/05
□ Microsoft MVP :Visual Developer ASP/ASP.NET Oct.2005-Sept.2006
_________________
ダッチ
大ベテラン
会議室デビュー日: 2005/10/31
投稿数: 113
投稿日時: 2005-12-05 12:32
回答ありがとうございます。

引用:

Jittaさんの書き込み (2005-12-05 06:19) より:

で、解決したの?
ってか、原因はわかっているんだから、解決したんだよね?

(メソッドに渡すところで new しているから、メソッドに渡すところの外で捕まえられないんだから、作ってから渡せばいいよね?)



解決はまだしておりません。
作ってから渡すという処理が出来ません。

MainWindow のApplication.Runに渡しているインスタンスを
Sub Mainのローカル変数などに一旦生成して
その生成したインスタンスをApplication.Runに渡したとしても
2回目以降に起動したプロセスから
どのようにして初回起動時のApplication.Runに渡したインスタンスを
取得するのがわかりません。

.NET Remoting については調べている最中です。


Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-12-05 21:32
 済みません、寝ぼけてました。


 .NET では、アプリケーションドメイン間通信を使うように、ということのようです。手っ取り早く、用意されているもので間に合わせるなら、TCP 通信をするアプリケーションを作成することになります。

 その他、自分で API 呼び出しをするなら、メッセージとか。
___________________________________________________________________
□ written by Jitta on 2005/12/05
□ Microsoft MVP for Visual Developer ASP/ASP.NET Oct.2005-Sept.2006
_________________
ダッチ
大ベテラン
会議室デビュー日: 2005/10/31
投稿数: 113
投稿日時: 2005-12-07 22:44
回答ありがとうございます。

引用:

Jittaさんの書き込み (2005-12-05 21:32) より:

その他、自分で API 呼び出しをするなら、メッセージとか。




.Net Remotingを調べていたのですが、奥が深いようで理解することが出来ませんでした。
そのためAPIを使用して多重起動した時にMainWindowに対してSendMessageでクリックメッセージを送信し、MainWindow側ではクリックイベントで新規作成処理を行うようにしたら無事に目的の動作をすることが出来ました。

MainWindowのハンドルを取得する処理にAPIのFindWindowを使用しているため少し不安が残りますが、今回はOKとしました。

.Net Remotingを使用することにより、
PC内でのプロセスを越えたメソッド呼び出しが出来そうなのは、わかりました。
しかし、具体的な処理が理解できなかったため今後の課題にしたいと思います。

皆さんのおかげで本来の目的とは違うMutexの扱いについても勉強できました。
ありがとうございました。

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