【问题标题】:ReadOnly Reference variables in a C# ClassC# 类中的只读引用变量
【发布时间】:2016-09-22 20:00:43
【问题描述】:

我有一个实例类,它实现了一个接口,并且除了接口方法之外的所有方法都是静态的。所有的类变量也是静态的。其中两个静态变量实际上是实例变量并标记为只读。这些只读实例变量是内联初始化的。

这是一个例子

public class Test : ITestInterface
{

  public static readonly DbConnection Connection = new DbConnection();

  public void static TestMethod1(){
  }

  public List<string> static TestMethod2(){
  }

}

我的框架层中有很多使用静态连接变量的方法。

这是一个有效的设计吗?我想对我的所有 API 调用使用相同的对象。这个想法是避免创建多个连接对象。在客户端调用负载的任何一天,都有可能创建 10,000 个连接对象。我试图避免这种情况。

【问题讨论】:

  • 这就是连接池的用途。连接对象应该是短暂的。在最后一刻创建它并尽快销毁它。让连接池负责创建/池连接以供重用。
  • 这不是Sqlconnection,它是一个第三方消息系统连接类。
  • 我严重怀疑这个第三方连接是线程安全的,这将使它很难正确使用。除非你真的只从一个线程调用它。您遇到的另一个主要问题是如果连接中断并变得无法使用会发生什么。你将如何安全地重新初始化它?
  • 谁关闭了连接?如果它使用非托管资源,谁来处理它?如果您尝试打开一个已经打开的连接怎么办?它是线程安全的吗?这些是静态资源造成的一些问题。创建数千个连接对象是否存在问题?
  • 当它的范围受到限制(在本例中为私有)并且永远不会进入无效状态时。即使这样,也只有当它是线程安全的,或者使用锁定来保证只有一个线程可以访问它时。经典示例:static readonly ILog logger = LogManager.GetLogger("name");.

标签: c# .net readonly reference-type


【解决方案1】:

这个想法是避免创建多个连接对象

用于处理这种情况的模式是Singleton 模式。您也不必必须以这种方式实施。但这是一般准则。

在您的具体示例中,您可以做的是渲染类private 的ctor。

public class Test : ITestInterface
{
  ...
  private Test() {}
  ..
}

这将使创建类的实例变得不可能,因此也无法从它派生。因此,您的 Test 类的消费者将别无选择,只能访问它的 static 成员。

但总的来说,我强烈建议您查看上面链接的模式。它可能会对您正在做什么以及如何您想这样做有所启发。

【讨论】:

  • 非常感谢。我会调查的
【解决方案2】:

几件事,首先你基本上将连接用作单例。这可以是一个完美的设计模式,但有许多考虑因素,我担心你会像你发布的那样使用它。

  1. 您是否有多个线程访问它?连接线程安全吗?所有变量都是线程安全的吗?如果不是,你就是在找麻烦。

  2. 您真的要在应用程序的整个生命周期中保持一个连接打开吗?如果连接关闭会发生什么?单身人士通常是处理这类问题的经理,而不是单一资源。

  3. 你知道多连接会低效吗?大多数连接层(如 SQL)管理一个连接池,可以非常有效地管理连接,并且您无需担心它。这通常是一种更好的模式,除非您可以通过性能计数器证明您可以更有效地自己管理连接

我会谨慎使用单例,并且仅在资源真正是全局且不变的以及线程安全的情况下使用。如果它是全局的,但需要围绕它进行管理和线程安全(想想连接),那么最好添加一个自定义管理器类。但同样,只有在您能证明您可以手动处理比使用普通连接池更多的连接和吞吐量时才这样做。

【讨论】:

  • 我的测试类是通过 IIS 的应用程序初始化功能运行的,并且只在一个线程中运行。
猜你喜欢
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多