Есть сервер и клиент, общающиеся по .NET Remoting. Сервер регистрирует объект с помощью RemotingServices.Marshal. Клиент получает ссылку через Activator.GetObject. Запускаю сервер, запускаю клиент. Несколько раз (обычно достаточно 5-10) быстро перезапускаю сервер (корректно или через Task Manager — неважно). Клиент при этом при каждой потере соединения пытается пересоединиться. После определенного количества попыток происходит следующее: на сервере в функции Marshal вываливается исключение RemotingException, что обнаружено 2 объекта по одному URI. И до перезапуска сервера никаким образом мне не получается заново зарегистрировать Remoting объект. Остановка клиента не помогает. Может ли мне кто-то объеяснить, что у меня происходит, и как этого избежать/обойти?
Здравствуйте, tealex, Вы писали:
T>может ошибка синхронизации ?
Похоже на то. Я вот поотлаживал повнимательней и понял, что происходит следующее. В промежуток между моментом, когда я регистрирую на сервере Wellknown тип (у меня он называется StatisticsServer), и моментом, когда я вызываю RemotingServices.Marshal для созданного мной объекта, клиент успевает подключиться к серверу и тем самым спровоцировать создание другого объекта StatisticsServer. И поэтому в функции Marshal генерируется исключение. Мне необходимо самому создавать объект StatisticsServer, чтобы инициализировать его должным образом. Я вижу 2 варианта решения:
1. Перенести регистрацию и вызов Marshal в одну функцию (сейчас между их вызовами проходит пара секунд и делается это в разных потоках).
2. При создании своего объекта проверять, не был ли он уже создан и если да, то использовать предыдущий объект (проводить доинициализацию).
Проще первый вариант. Но возникает вопрос, достаточно ли будет вызывать функции в одном потоке или теоретически все же возможно, что между регистрацией и Marshal клиент успеет подключиться, и ситуация повторится?
не знаю подойдёт ли это вам
но для того что бы все клиенты обращались к одному обеькту достаточно использовать static
ваш класс MainClass , сначала создаёте экземпляр mainClass , потом регистрируете в Remoting класс обёртку Remote , вызов метода Method, будет вызываться метод статического класса
static MainClass mainClass;
public class Remote : MarshalByRefObject,
{
public override object InitializeLifetimeService()
{
ILease x = (ILease)base.InitializeLifetimeService();
if (x.CurrentState == LeaseState.Initial)
{
x.InitialLeaseTime = TimeSpan.FromSeconds(0); // поставить 0
}
return x;
}
#region
public string Method(Class r)
{
return mainClass.Method(r);
}
#endregion
}