- PR -

処理時間のかかるリモートオブジェクトのメソッドを呼び出すとエラーになるのですが

投稿者投稿内容
アッキー
会議室デビュー日: 2004/09/23
投稿数: 4
投稿日時: 2004-09-23 22:01
実行環境
WindowsXP Pro SP1
.NET Framework1.1 SP1

Singleton型リモートオブジェクトを使用しています。
処理に時間がかかるメソッドを実行すると120秒前後のところで
必ず、例外(System.Runtime.Remoting.RemotingException等)が発生してしまいます。

試しにマイクロソフトのサンプル

http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpguide/html/cpconremotingexamplehostinginiis.asp

にThread.Sleepでウエイトを挿入すると同様の現象が発生しました。

念のためにSingleton用のサンプル(一番下に貼っておきます)も作って見ましたが結果は一緒でした。

ウエイトを120秒にすると必ず落ちます。
どんどん時間を減らしていくと105秒では落ちるが104秒だとOKでした。

この現象はIISをリモートオブジェクトのコンテナにした場合のみに発生しています。

フォーマッタをバイナリ、XMLどちらにしてもダメでした。

リース期間、タイムアウトを設定してもダメでした。

デリゲートを使用した非同期呼び出しを行ってもダメでした。


回避方法をご存知の方がいらっしゃいましたら、ぜひご教授おねがいします。



現象再現サンプル
コード:
------------------------ ServiceClass.cs ------------------------
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Threading;
using System.Web;

public class ServiceClass : MarshalByRefObject {
   public string GetServerString(){
      Thread.Sleep(1000 * 120);
      return "Hi";
   }
}

------------------------ Web.config ------------------------

<configuration>
   <system.runtime.remoting>
      <application>
         <service>
            <wellknown mode="Singleton" type="ServiceClass, ServiceClass" objectUri="ServiceClass.rem"/>
         </service>
         <channels>
            <channel ref="http"/>
         </channels>
      </application>
   </system.runtime.remoting>
</configuration>

------------------------ Client.cs ------------------------

using System;
using System.Collections;
using System.Diagnostics;
using System.Net;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Security.Principal;

public class Client {
   public static void Main(string[] Args){
        ServiceClass service = (ServiceClass)Activator.GetObject(typeof(ServiceClass), 
                                "http://localhost/HttpBinary/ServiceClass.rem");
        Console.WriteLine("The server says : " + service.GetServerString());
   }
}



nanbu
大ベテラン
会議室デビュー日: 2004/08/19
投稿数: 178
投稿日時: 2004-09-24 02:09
南部です。

> 例外(System.Runtime.Remoting.RemotingException等)
等、、、なので、勝手に推測します。
外れていたらすみません。

その1:
-- 例外 --
System.Net.WebException: 基になる接続が閉じられました : 受信時に予期しないエラーが発生しました。
----------
この場合は、IISのWebサイトのプロパティで
「接続タイムアウト」を増やして下さい。


その2:
-- 例外 --
System.Runtime.Remoting.RemotingException:
<html> ............

もしくは、

System.Runtime.Serialization.SerializationException: BinaryFormatter バージョンに互換性がありません。バージョン 1.0 が必要ですが、バージョン 1008738336.1684104552 を受け取りました。
------
の場合、
Web.configの
/configuration/system.web要素の子に
<httpRuntime executionTimeout="180"/>
を追加して下さい。
なお、executionTimeoutの単位は秒で、
既定値は90(machine.configの値)です。

なお、こちらでの動作確認環境は
Windows Server 2003
.NET Framework 1.1 SP1
です。

アッキー
会議室デビュー日: 2004/09/23
投稿数: 4
投稿日時: 2004-09-24 07:28
南部さんのおっしゃるとおりWeb.conigに追加したら
正常に動作しました。どうもありがとうございます!
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-09-25 07:52
 正常?何をもって“正常”とするの?たとえば、タイムアウト時間を180秒と設定して、実際に処理に200秒かかったら、どうするの?200秒ですむのだったら、250とかに設定すればいいけど、その上限はどうやったら出てくるの?その辺の設計を見直す必要があるんじゃない?
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2004-09-25 10:35
本当にタイムアウトが発生するほど時間のかかる処理を行うなら、インターフェースの設計を見直したほうが良い。要求w受けた時点でバックグラウンドで処理を開始、データの取得は別のメソッドにするとかね。
nanbu
大ベテラン
会議室デビュー日: 2004/08/19
投稿数: 178
投稿日時: 2004-09-26 18:38
南部です。

Jittaさんの投稿にあるような視点はとても重要だと思います。
実際の業務レベルでは、どのように実装するのでしょう?

Jittaさん、甕星さんは、
「タイムアウト時間の設定に依存しないように設計を見直すべき」
という意見であると解釈しましたが(間違いであればご指摘下さい)、
甕星さんの投稿のように、
「タイムアウトが発生するほど時間のかかる処理はバックグラウンドで処理する」
とういうような実装にすべきなのでしょうか。

私は安易に、通常の運用では考えられない処理時間を
タイムアウトに設定すればいいかなと考えてしまいました。
例えば、業務時間が8時間と想定されているならそれを超えた場合はエラーにする、と。
httpRuntimeのexecutionTimeoutはこのような使用目的であり、
IISをホストとしたときの恩恵のひとつと認識していたためです。

なので、「設計を見直す」という意見の根拠がイマイチ、ピンときません。
「実務ではこうすべき」とか、
「こうするのが行儀がよい」
という意見があれば、ぜひ、ご教授願いたいと思います。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-09-27 06:22
引用:

nanbuさんの書き込み (2004-09-26 18:38) より:

なので、「設計を見直す」という意見の根拠がイマイチ、ピンときません。
「実務ではこうすべき」とか、
「こうするのが行儀がよい」
という意見があれば、ぜひ、ご教授願いたいと思います。



 ほう!では、8時間、黙りになった端末の前で待ちますか?

 もし、誰も操作する人がいない端末で行うものであったり、バックグラウンドで人知れず行う処理であれば、それでもいいでしょう。しかし、何らかの形で人間が関わる処理であれば、遅くても1分以内、できれば20秒、最良は3秒以内にフィードバックを返すべきです。「お待ちください」を出したとしても、3分も待たせてはいけません。「お待ち管債を出したまま、止まっているのではないか」と思わせます。

#1分、20秒は経験的な感覚によるもの
#3秒は何かのガイドで提示されていた値
nanbu
大ベテラン
会議室デビュー日: 2004/08/19
投稿数: 178
投稿日時: 2004-09-27 11:09
引用:

Jittaさんの書き込み (2004-09-27 06:22) より:

 もし、誰も操作する人がいない端末で行うものであったり、バックグラウンドで人知れず行う処理であれば、それでもいいでしょう。




なるほど、OKである場合もあるのですね。
アッキーさんの場合は、どういった処理だったのでしょう。
先の投稿で、処理内容には触れず「設計を見直す」という言葉が使用されていたため、
.NETリモーティングのホストをIISにする場合の、「共通の」
「実務ではこうすべき」とか、
「こうするのが行儀がよい」
パターンがあるのでは、と思いました。

引用:

Jittaさんの書き込み (2004-09-27 06:22) より:

しかし、何らかの形で人間が関わる処理であれば、遅くても1分以内、できれば20秒、最良は3秒以内にフィードバックを返すべきです。「お待ちください」を出したとしても、3分も待たせてはいけません。



これに関しては、
1.クライアント側で非同期呼び出しを使う方法と、
2.甕星さんの投稿のように、リモートメソッド内で実装する方法が思いつきますが、
.NET リモーティングのようなRPCの場合は、どのように実装するのがよりよいのでしょう。
私が見かけたサンプルでは、1.の非同期呼び出ししかありませんでした。

やはり、実行する処理によって使い分けるものなのでしょうか。

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