.NET Remoting: Marshal при быстром перезапуске сервера
От: SeninAndrew Россия  
Дата: 30.10.09 16:49
Оценка:
Есть сервер и клиент, общающиеся по .NET Remoting. Сервер регистрирует объект с помощью RemotingServices.Marshal. Клиент получает ссылку через Activator.GetObject. Запускаю сервер, запускаю клиент. Несколько раз (обычно достаточно 5-10) быстро перезапускаю сервер (корректно или через Task Manager — неважно). Клиент при этом при каждой потере соединения пытается пересоединиться. После определенного количества попыток происходит следующее: на сервере в функции Marshal вываливается исключение RemotingException, что обнаружено 2 объекта по одному URI. И до перезапуска сервера никаким образом мне не получается заново зарегистрировать Remoting объект. Остановка клиента не помогает. Может ли мне кто-то объеяснить, что у меня происходит, и как этого избежать/обойти?

Заранее спасибо.
Re: пример кода , было бы хорошо
От: tealex  
Дата: 01.11.09 18:11
Оценка:
если бы был простой пример кода воспроизводящего Exception было бы проще..

может ошибка синхронизации ?
хана
Re[2]: пример кода , было бы хорошо
От: SeninAndrew Россия  
Дата: 01.11.09 18:59
Оценка:
Здравствуйте, tealex, Вы писали:

T>может ошибка синхронизации ?


Похоже на то. Я вот поотлаживал повнимательней и понял, что происходит следующее. В промежуток между моментом, когда я регистрирую на сервере Wellknown тип (у меня он называется StatisticsServer), и моментом, когда я вызываю RemotingServices.Marshal для созданного мной объекта, клиент успевает подключиться к серверу и тем самым спровоцировать создание другого объекта StatisticsServer. И поэтому в функции Marshal генерируется исключение. Мне необходимо самому создавать объект StatisticsServer, чтобы инициализировать его должным образом. Я вижу 2 варианта решения:

1. Перенести регистрацию и вызов Marshal в одну функцию (сейчас между их вызовами проходит пара секунд и делается это в разных потоках).
2. При создании своего объекта проверять, не был ли он уже создан и если да, то использовать предыдущий объект (проводить доинициализацию).

Проще первый вариант. Но возникает вопрос, достаточно ли будет вызывать функции в одном потоке или теоретически все же возможно, что между регистрацией и Marshal клиент успеет подключиться, и ситуация повторится?
Re[3]: пример кода , было бы хорошо
От: tealex  
Дата: 02.11.09 18:56
Оценка:
сложно понять без кода ...

не знаю подойдёт ли это вам
но для того что бы все клиенты обращались к одному обеькту достаточно использовать 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

}


регистрируете
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Remote), "XXX.tcp", WellKnownObjectMode.Singleton);


или смотреть Singleton
http://ru.wikipedia.org/wiki/%D0%9E%D0%B4%D0%B8%D0%BD%D0%BE%D1%87%D0%BA%D0%B0_%28%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%29#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80_C.23

хотя не знаю как он с remoting работает ....
хана
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.