Здесь есть два возможных решения.
Подход Singleton: переопределить InitializeLifetimeService
Как Саша Гольдштейн указывает на сообщение в блоге , на которое ссылается оригинальный постер, если у вашего объекта Marshaled есть семантика Singleton, вы можете переопределить InitializeLifetimeService
:
class MyMarshaledObject : MarshalByRefObject
{
public bool DoSomethingRemote()
{
// ... execute some code remotely ...
return true;
}
[SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.Infrastructure)]
public override object InitializeLifetimeService()
{
return null;
}
}
Однако, как user266748 указывает в другой ответ
это решение не сработало бы, если бы такой объект создавался каждый раз
клиент подключается сам, потому что они никогда не будут GCed и ваш
потребление памяти будет расти, пока вы не остановите
сервер или происходит сбой, потому что у него больше нет памяти
Подход на основе классов: использование ClientSponsor
Более общим решением является использование ClientSponsor
для продления срока службы удаленного объекта, активируемого классом. В связанной статье MSDN есть полезный стартовый пример, которому вы можете следовать:
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Lifetime;
namespace RemotingSamples
{
class HelloClient
{
static void Main()
{
// Register a channel.
TcpChannel myChannel = new TcpChannel ();
ChannelServices.RegisterChannel(myChannel);
RemotingConfiguration.RegisterActivatedClientType(
typeof(HelloService),"tcp://localhost:8085/");
// Get the remote object.
HelloService myService = new HelloService();
// Get a sponsor for renewal of time.
ClientSponsor mySponsor = new ClientSponsor();
// Register the service with sponsor.
mySponsor.Register(myService);
// Set renewaltime.
mySponsor.RenewalTime = TimeSpan.FromMinutes(2);
// Renew the lease.
ILease myLease = (ILease)mySponsor.InitializeLifetimeService();
TimeSpan myTime = mySponsor.Renewal(myLease);
Console.WriteLine("Renewed time in minutes is " + myTime.Minutes.ToString());
// Call the remote method.
Console.WriteLine(myService.HelloMethod("World"));
// Unregister the channel.
mySponsor.Unregister(myService);
mySponsor.Close();
}
}
}
Ничего не стоит, как управление жизненным циклом работает в API удаленного взаимодействия, который довольно хорошо описан здесь, в MSDN . Я процитировал ту часть, которая мне показалась наиболее полезной:
Сервис удаленного взаимодействия связывает аренду с каждой услугой,
и удаляет сервис, когда истекает срок его аренды. Время жизни
сервис может взять на себя функцию традиционного распределенного мусора
коллектор, и он также корректируется, когда количество клиентов в
Сервер увеличивается.
В каждом домене приложения есть менеджер по аренде, который отвечает за
для контроля аренды в своем домене. Все договоры аренды рассматриваются
периодически для истекших сроков аренды. Если срок аренды истек, один или
больше спонсоров аренды призваны и получили возможность
возобновить аренду. Если ни один из спонсоров не решит продлить договор аренды,
менеджер по аренде снимает аренду, и объект может быть забран
сборщик мусора. Менеджер по аренде ведет список аренды с
аренды отсортированы по оставшемуся времени аренды. Аренда с самым коротким
оставшееся время хранится в верхней части списка. Remoting
Пожизненная служба связывает аренду с каждой службой и удаляет
обслуживание, когда срок его аренды истекает.