在 .NET Remoting 中使用 Singleton 与 Single Call?

发布于 2024-08-05 03:23:57 字数 185 浏览 8 评论 0原文

到目前为止,我编写或使用的所有 .NET 远程处理代码都已公开为 SingleCall。

我遇到了一个托管在 Windows 服务中的 .NET 远程处理组件,该组件作为单例公开。

该对象有可能被多个客户端同时调用,并且它没有锁或其他规定来保护其内部状态。

如果我正确理解单例,那么这有可能产生大问题,对吗?

Up until this point all the .NET remoting code I have written or worked with has been exposed as SingleCall.

I ran across a .NET remoting component hosted in a Windows service that is exposed as a Singleton.

This object has the potential to be called by more than one client at the same time, and it has no locks or other provisions to protect its internal state.

If I understand Singleton correctly then this has the potential for big problems correct?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱情眠于流年 2024-08-12 03:23:57

没有比 SingleCall 组件更大的潜力。如果尝试以不安全的方式访问共享内存位置,两者都会出现问题。

SingleCall 和 Singleton 之间的区别在于,对于 SingleCall ,每个传入请求都将获得为处理该调用而创建的已定义类型的新实例。每个实例都有自己的内存空间和实例变量,但它们仍然可以共享静态和全局变量、外部资源、文件、网络连接等。如果 SingleCall 类被编码为以线程不安全的方式访问任何共享内存状态,那么你就会遇到问题。

另一方面,单例只会为所有传入请求创建一个实例,因此根据定义,该单例中使用的每个实例变量实际上在所有传入请求之间共享。一个很好的例子可能是消息发布者,服务器中的所有代码都需要访问它才能将消息发送到一个或多个订阅的客户端......

方法

  MarshalByRefObject.InitializeLifetimeService() 

要解决来自 @Cocowalla 的评论,请确保如果您这样做,您会重写所示的 ,或者如果一段时间内没有人调用你的单身人士会意外死亡......

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);

No more potential than a SingleCall component. Both will have problems if they attempt to access a shared memory location in an unsafe manner.

The difference between SingleCall and Singleton is that, for SingleCall , every incoming request will get a new instance of the defined type created to handle that call. Each instance will have its own memory space and instance variables, but they can still share static and global variables, external resources, files, network connections, etc. If the SingleCall class is coded to access any shared memory state in a thread-unsafe manner, then you will have issues.

A Singleton, on the other hand, only gets one instance created for ALL incoming requests, so by definition, every instance variable in use within that singleton is, in fact, shared among all incoming requests. A good example might be a message publisher, that all code in the server needs to access to send messages to one or more subscribed clients....

To address comment from @Cocowalla, make sure if you do this you override the method

  MarshalByRefObject.InitializeLifetimeService() 

as shown, or your singleton will die out unexpectedly if no one calls it for a while...

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);
開玄 2024-08-12 03:23:57

是的。如果调用者改变了对象的内部状态,并且这些方法不是线程安全的,那么您一定会遇到麻烦。该服务器应该是单调用的。

但正如 Charles 指出的那样,如果服务器对象访问共享资源(还有什么有用的服务器不访问共享资源呢?),即使是单调用服务器也会遇到麻烦。不过,这些问题更容易控制。例如,对数据库的访问可以很容易地变成事务性的,因此是安全的。

底线:进行一次通话是摆脱“一半”麻烦的简单而有效的方法。坚持下去。

Yes. If the callers alter the object's internal state, and those methods are not thread-safe, then you're bound to get into trouble. That server should be single-call.

But as Charles points out, if the server object accesses shared resources (and what useful server doesn't?), even single-call servers can get into trouble. Still, those problems are more manageable. Access to a database, for example, can quite easily be made transactional, and hence safe.

Bottom line: going for single-call is a simple and effective way of getting rid of 'half' your troubles. Stick to it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文