2009-09-16 2 views
1

До этого момента весь удаленный код .NET, с которым я написал или работал, был разоблачен как SingleCall.Использование Singleton vs Single Call в .NET Remoting?

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

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

Если я правильно понимаю Синглтон, у этого есть потенциал для устранения больших проблем?

+0

«нет замков или других положений для защиты своего внутреннего состояния» ... вы уверены, что это Синглтон? Я понимаю, что вам нужно иметь блокировку для ограничения (начальной) конструкции для одного потока. –

ответ

8

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

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

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

Чтобы ответить на комментарий от @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); 
+0

Вам нужно будет опасаться жизни Singleton, хотя, в зависимости от вашей конфигурации, ваш Singleton, который вы ожидаете быть включенным во время работы приложения, фактически может быть автоматически уничтожен и воссоздан. В удаленном режиме синглтоны имеют заданную «аренду» или «продолжительность жизни», после чего они автоматически будут уничтожены. Можно изменить время жизни, или даже продлить его на неопределенный срок, но это то, о чем нужно знать. Дополнительная информация: http://www.thinktecture.com/resourcearchive/net-remoting-faq/singletonisdying http://msdn.microsoft.com/en-us/magazine/cc300474.aspx – Cocowalla

2

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

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

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