我有一个用 c# 编写的 IIS 托管 Web 应用程序。在服务调用中,它会创建一个新的 AppDomain 并在加载后执行一个 dll。当执行时间超过 10 分钟时,我收到以下远程处理异常:
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 并且类似地尝试获得无限制的租约,如上所述。
我也试图让我的服务对象成为一个 ISponsor 并且在 Renew 我做
public TimeSpan Renewal(ILease lease)
{
return TimeSpan.FromMinutes(5);
}
但是从不调用 Renewal。我已经在 Google 上查找了所有链接和堆栈溢出,但找不到解决方案。可能是什么问题?