Использование Singleton против Single Call в .NET Remoting? - PullRequest
1 голос
/ 16 сентября 2009

До этого момента весь код удаленного взаимодействия .NET, с которым я писал или работал, выставлялся как SingleCall.

Я столкнулся с компонентом удаленного взаимодействия .NET, размещенным в службе Windows, которая отображается как Singleton.

Этот объект может быть вызван более чем одним клиентом одновременно, и у него нет блокировок или других условий для защиты его внутреннего состояния.

Если я правильно понимаю Синглтон, то это может привести к серьезным проблемам?

Ответы [ 2 ]

8 голосов
/ 16 сентября 2009

Не больше потенциала, чем у компонента SingleCall. У обоих будут проблемы, если они попытаются получить доступ к общей памяти в небезопасной манере.

Разница между SingleCall и Singleton заключается в том, что для SingleCall каждый входящий запрос получает новый экземпляр определенного типа, созданный для обработки этого вызова. Каждый экземпляр будет иметь свое собственное пространство памяти и переменные экземпляра, но они по-прежнему могут совместно использовать статические и глобальные переменные, внешние ресурсы, файлы, сетевые подключения и т. Д. Если класс SingleCall закодирован для доступа к любому состоянию общей памяти небезопасным для потока способом тогда у вас будут проблемы.

Синглтон, с другой стороны, получает только один экземпляр, созданный для ВСЕХ входящих запросов, поэтому по определению каждая переменная экземпляра, используемая в этом синглтоне, фактически является общей для всех входящих запросов. Хорошим примером может служить издатель сообщений, которому необходим весь код на сервере для отправки сообщений одному или нескольким подписанным клиентам ....

Чтобы обратиться к комментарию от @Cocowalla, убедитесь, что если вы сделаете это, вы переопределите метод

  MarshalByRefObject.InitializeLifetimeService() 

, как показано, или ваш синглтон неожиданно исчезнет, ​​если никто не вызовет его некоторое время ...

public class MessageManager : MarshalByRefObject
{
    #region Singleton / MarshalByRefObject code        
    private static MessageManager mgr = 
        new MessageManager(); // creates singleton 
    static MessageManager() { }
    private MessageManager() { }
    public static MessageManager Instance { get { return mgr;  } }
    public override object InitializeLifetimeService() { return (null); }
    #endregion Singlelton code
    // ... other stuff ... 
 }

  // in Remoting Host initialization code...      
   MessageManager mgr = MessageManager.Instance; // generates singleton;
   RemotingServices.Marshal(mgr, URI);
2 голосов
/ 16 сентября 2009

Да. Если вызывающие стороны изменяют внутреннее состояние объекта, и эти методы не являются поточно-ориентированными, тогда вы обязательно попадете в беду. Этот сервер должен быть однократным.

Но, как указывает Чарльз, если объект сервера получает доступ к общим ресурсам (а какой полезный сервер нет?), Даже серверы с одним вызовом могут столкнуться с проблемами. Тем не менее, эти проблемы более управляемы. Например, доступ к базе данных можно легко сделать транзакционным и, следовательно, безопасным.

Итог: переход на одиночный вызов - это простой и эффективный способ избавления от «половины» ваших проблем. Придерживайтесь этого.

...