1

C# で記述された IIS でホストされている Web アプリがあります。サービス呼び出しで、新しい AppDomain を作成し、それを読み込んだ後に dll を実行します。実行時間が 10 分を超えると、次の Remoting 例外が発生します。

System.Runtime.Remoting.RemotingException: オブジェクト '/a3178091_1732_4272_b0bd_dae31e328450/lwntwiaw53jg1rd9gbvsigbe_25.rem' が切断されたか、サーバーに存在しません。

サーバー スタック トレース:

System.Runtime.Remoting.Channels.ChannelServices.CheckDisconnectedOrCreateWellKnownObject (IMessage メッセージ) で

System.Runtime.Remoting.Channels.ChannelServices.SyncDispatchMessage (IMessage メッセージ) で

[0] で例外が再スローされました:

System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage (IMessage reqMsg、IMessage retMsg) で

System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (MessageData& msgData、Int32 型) で

System.IO.Stream.set_Position (Int64 値) で

アプリドメインを作成する方法は次のとおりです

    private AppDomain CreateDomainForTaskExecution(string baseDirectory)
    {
        AppDomainSetup domainSetup = new AppDomainSetup();
        domainSetup.ApplicationBase = baseDirectory;
        domainSetup.PrivateBinPath = baseDirectory;
        return AppDomain.CreateDomain("Domain for task execution", null, domainSetup);
    }

次に、サービス呼び出しでリモート オブジェクトを呼び出します。

   newDomain = CreateDomainForTaskExecution(domainBaseDir);


            IExecutableTaskFactory taskLocator = (IExecutableTaskFactory)newDomain.CreateInstanceFromAndUnwrap(taskAssemblyFile.FullName, this.ExecutableTaskFactoryFullName);
            IExecutableTask executableTask = taskLocator.Create();
    IList<uint> ouputArguments = executableTask.OutputArgumentNames;

        IDictionary<uint, Stream> taskOutput = new Dictionary<uint, Stream>();
        foreach (uint argument in ouputArguments)
        {
            MarshalByRefObject stream = new MemoryStream();
            taskOutput[argument] = stream as Stream;
            ILease lease = (ILease)stream.InitializeLifetimeService();
            if (lease.CurrentState == LeaseState.Initial)
            {
                lease.InitialLeaseTime = TimeSpan.Zero;
                //lease.SponsorshipTimeout = TimeSpan.FromMinutes(30);
                //lease.RenewOnCallTime = TimeSpan.FromMinutes(30);
            }
            lease.Register(this);
        }

        // Register as a sponsor.
        foreach (Stream stream in inputArguments.Values)
        {
            ILease lease = (ILease)stream.InitializeLifetimeService();
            if (lease.CurrentState == LeaseState.Initial)
            {
                lease.InitialLeaseTime = TimeSpan.Zero;
                //lease.SponsorshipTimeout = TimeSpan.FromMinutes(30);
                //lease.RenewOnCallTime = TimeSpan.FromMinutes(30);
            }
            lease.Register(this);
        }

        executableTask.Execute(inputArguments, taskOutput);
        return taskOutput;

taskLocator は MarshalByRefObject であり、次のように InitializeLifetimeService() 関数をオーバーライドします。

    public override object InitializeLifetimeService()
    {
        ILease lease = (ILease)base.InitializeLifetimeService();
        if (lease.CurrentState == LeaseState.Initial)
        {
            lease.InitialLeaseTime = TimeSpan.Zero;
            //lease.SponsorshipTimeout = TimeSpan.FromMinutes(30);
            //lease.RenewOnCallTime = TimeSpan.FromMinutes(30);
        }
        return lease;
    }

executableTask も MarshalByRefObject であり、同様に上記のように無制限の Lease を取得しようとします。

また、サービス オブジェクトを ISponsor にしようとしましたが、Renew でそうします

    public TimeSpan Renewal(ILease lease)
    {
        return TimeSpan.FromMinutes(5);
    }

しかし、更新は決して呼び出されません。Google とスタック オーバーフローですべてのリンクを調べましたが、解決策が見つかりませんでした。考えられる問題は何ですか?

4

0 に答える 0