トップ回答者
FW2.0における.NETリモーティングの異常終了

質問
-
TCPコネクションの.NETリモーティングで、クライアントEXEを終了すると、サーバー側でAccessViolationExceptioが発生し、サーバーのプロセスが強制終了してしまいます。
.NET Frameworkのバージョンが v1.1.4322 では問題なく動作をするのですが、v2.0.50727でコンパイルをしたものは、上記の現象が起きます。
2.0になると呼び出し方が違うのでしょうか?
原因が分からず、悩んでおります。お手数ですが、教えていただければ幸いです。ソースは、MSDNにある単純なものを使用しました。
http://msdn2.microsoft.com/ja-JP/library/ecc85927.aspx-- クライアント側コード --
Public Class Client
Public Shared Sub Main()
RemotingConfiguration.Configure("Client.exe.config", false)
Dim remoteObject As New RemotableType()
Console.WriteLine(remoteObject.StringMethod())
End Sub 'Main
End Class<configuration>
<system.runtime.remoting>
<application>
<client>
<wellknown
type="RemotableType, RemotableType"
url="tcp://localhost:8085/RemotableType.rem" />
</client>
</application>
</system.runtime.remoting>
</configuration>-- サーバー側コード --
Public Class Listener
Public Shared Sub Main()
RemotingConfiguration.Configure("Listener.exe.config", false)
Console.WriteLine("Listening for requests. Press Enter to exit...")
Console.ReadLine()
End Sub 'Main
End Class<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown
mode="SingleCall" type="RemotableType, RemotableType"
objectUri="RemotableType.rem" />
</service>
<channels>
<channel ref="tcp" port="8085"/>
</channels>
</application>
</system.runtime.remoting>
</configuration>-- リモート呼び出しの関数 --
Public Class RemotableType
Inherits MarshalByRefObject
Private StringValue As String = "This is the RemotableType."Public Function StringMethod() As String
Return StringValue
End Function 'StringMethod
End Class
回答
すべての返信
-
取りあえず手元の環境でリンクにあったMSDNのチュートリアルを元にコーディング・バッグをしてみましたが、書かれているような問題は発生しませんでした。
Modeも書かれているようにmsdnのチュートリアルでのSingletonからSingleCallに変更しましたが問題有りませんでした。
書かれている内容だと、リモートメソッドの呼び出しには成功されているようなので、App.ConfigのType属性の指定が間違いというわけでもなさそうですね。
基本的にこのエクセプションが発生した理由はサーバー側でRemotingによってクライアントからのメソッド呼び出し時に作成されたRemotableTypeクラスのインスタンスが、クライアントの終了前に破棄されたためだと推察できます。設定したリース期間(この場合はデフォルト設定値)以上クライアント側をステップ実行させたままどこかで止めておくなどして、クライアントを生かしておくと、こういう事になる事があります。
リースの概念はRemotingの素敵なところですので、以下で押さえておくと良いですよ。
RemotingはDCOMのと違って一度アクティベートしたら何時までも向こうで待っていてくれるというわけではないのよ。(分散ガベージコレクションの考え方が根本的に違う)
-
お返事どうもありがとうございました。
また、ソースから、SingletonからSingleCallの変更点を読み取っていただき、ありがとうございます。
変更点を載せるべきでしたね。すいません。
一応、状況をまとめておきます。----------------------------------------------------
◇動作環境
v2.0.50727◇MSDNサンプルからの変更点
①チャネルの変更
<channel ref="http" port="8085"/>
↓
<channel ref="tcp" port="8085"/>②モードの変更
mode="Singleton"
↓
mode="SingleCall"③関数の変更
RemotingConfiguration.Configure("Listener.exe.config")
↓
RemotingConfiguration.Configure("Listener.exe.config", false)
◇現象
クライアントから.NETリモーティングにより関数を呼び出した後、
(このときは正常に動作)、クライアントEXEを終了した際に、
サーバー側で、でAccessViolationExceptionが発生。
ただし、v1.1.4322では、正常に動作。
----------------------------------------------------ご指摘のあった、リースのことを考慮せずに組んでおりました。
私自身、リースの概念を抑え切れていなかったので、
もう一度、調査をして、試してみます。