在 C# 中实现 Singleton

C#多线程Singleton(单件)模式模板 下面是一个C#多线程单件模式的代码模板。把T换成你自己的类型就可以使用了。其精妙之处就在于用lock语句锁定资源来避免多线程同时走入if语句去创建多个对象 立即下载

在 C# 中实现 Singleton (来源MSDN技术文章)

发布日期 : 4/1/2004 | 更新日期 : 4/19/2004
使用 Microsoft .NET 的企业解决方案模式 > 分布式系统模式 > 在 C# 中实现 Singleton

版本: 1.0.1

 
本页内容
 上下文
 实现策略
 结果上下文
 致谢


上下文
您要在 C# 中构建应用程序。您需要只有一个实例的类,并且需要提供一个用于访问实例的全局访问点。您希望确保您的解决方案高效,并且能够利用 Microsoft? .NET 公共语言运行库功能。您可能还希望确保解决方案是线程安全的。

 返回页首

实现策略
尽管 Singleton 是一种相对简单的模式,但是存在与具体实现有关的不同权衡因素和选项。下面是一组实现策略,及其优缺点的讨论。

Singleton
Singleton 设计模式的下列实现采用了 Design Patterns: Elements of Reusable Object-Oriented Software [Gamma95] 中所描述的解决方案,但对它进行了修改,以便利用 C# 中可用的语言功能,如属性:

using System;
public class Singleton
{
   private static Singleton instance;
   private Singleton() {}
   public static Singleton Instance
   {
      get 
      {
         if (instance == null)
         {
            instance = new Singleton();
         }
         return instance;
      }
   }
}
该实现主要有两个优点:

由于实例是在 Instance 属性方法内部创建的,因此类可以使用附加功能(例如,对子类进行实例化),即使它可能引入不想要的依赖性。

直到对象要求产生一个实例才执行实例化;这种方法称为"懒实例化"。懒实例化避免了在应用程序启动时实例化不必要的 singleton。

但是,这种实现的主要缺点是在多线程环境下它是不安全的。如果执行过程的不同线程同时进入 Instance 属性方法,那么可能会创建多个 Singleton 对象实例。每个线程都会执行下列语句,并决定必须创建新的实例:

if (instance == null)
解决此问题的方法有很多。一种方法是使用被称为 Double-Check Locking [Lea99] 的技术。而 C# 与公共语言运行库也提供了一种"静态初始化"方法,这种方法不需要开发人员显式地编写线程安全代码,即可解决这些问题。

静态初始化
One of the reasons Design Patterns [Gamma95] 避免使用静态初始化的原因之一是,C++ 规范在静态变量的初始化顺序方面留下了一些多义性。幸运的是,.NET Framework 通过其变量初始化处理方法解决了这种多义性:

public sealed class Singleton
{
   private static readonly Singleton instance = new Singleton();
   private Singleton(){}
   public static Singleton Instance
   {
      get 
      {
         return instance; 
      }
   }
}
在此策略中,将在第一次引用类的任何成员时创建实例。公共语言运行库负责处理变量初始化。该类标记为 sealed 以阻止发生派生,而派生可能会增加实例。有关将类标记为 sealed 的利与弊的讨论,请参阅 [Sells03]。此外,变量标记为 readonly,这意味着只能在静态初始化期间(此处显示的示例)或在类构造函数中分配变量。

该实现与前面的示例类似,不同之处在于它依赖公共语言运行库来初始化变量。它仍然可以用来解决 Singleton 模式试图解决的两个基本问题:全局访问和实例化控制。公共静态属性为访问实例提供了一个全局访问点。此外,由于构造函数是私有的,因此不能在类本身以外实例化 Singleton 类;因此,变量引用的是可以在系统中存在的唯一的实例。

由于 Singleton 实例被私有静态成员变量引用,因此在类首次被对 Instance 属性的调用所引用之前,不会发生实例化。因此,与 Design Patterns 形式的 Singleton 一样,该解决方案实现了懒实例化属性的一种形式。

这种方法唯一的潜在缺点是,您对实例化机制的控制权较少。在 Design Patterns 形式中,您能够在实例化之前使用非默认的构造函数或执行其他任务。由于在此解决方案中由 .NET Framework 负责执行初始化,因此您没有这些选项。在大多数情况下,静态初始化是在 .NET 中实现 Singleton 的首选方法。

多线程 Singleton
静态初始化适合于大多数情形。如果您的应用程序必须延迟实例化、在实例化之前使用非默认的构造函数或执行其他任务、并且工作在多线程环境中,那么您需要另一种解决方案。但是,在一些情况下,您无法像在"静态初始化"示例中那样依赖公共语言运行库来确保线程的安全性。在这种情况下,必须使用特定的语言功能来确保在存在多线程的情况下仅创建一个对象实例。更常见的解决方案之一是使用 Double-Check Locking [Lea99] 技术来阻止不同的线程同时创建 singleton 的新实例。

注意:公共语言运行库解决了在其他环境中常见的、与使用 Double-Check Locking 有关的问题。有关这些问题的详细信息,请参阅马里兰大学计算机科学系网站中的"The 'Double-Checked Locking Is Broken' Declaration",网址为 http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html.

下面的实现仅允许一个线程在尚未创建 Singleton 实例的情况下进入关键区域(该区域由 lock 块标识)。

using System;
public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();
   private Singleton() {}
   public static Singleton Instance
   {
      get 
      {
         if (instance == null) 
         {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }
         return instance;
      }
   }
}
此方法确保了仅在需要实例时才会创建仅一个实例。此外,变量被声明为 volatile,以确保只有在实例变量分配完成后才能访问实例变量。最后,此方法使用 syncRoot 实例来进行锁定(而不是锁定类型本身),以避免发生死锁。

此 double-check locking 方法解决了线程并发问题,同时避免在每个 Instance 属性方法的调用中都出现独占锁定。它还允许您将实例化延迟到第一次访问对象时发生。实际上,应用程序很少需要这种类型的实现。大多数情况下,静态初始化方法已经够用。

 返回页首

结果上下文
在 C# 中实现 Singleton 具有下列优缺点:

优点

由于 .NET Framework 显式地指定静态变量初始化如何以及何时发生,因此静态初始化方法是可能的。

列的前面的"多线程 Singleton"中所描述的 Double-Check Locking 技术已在公共语言运行库中正确实现。

缺点

如果您的多线程应用程序需要进行显式初始化,那么必须采取措施以避免线程问题。

 

ArcGIS基础:CAD数据转换为GIS数据(符号化显示、数据转换、线转面、空间连接) 1、符号化显示: CAD数据加载进来有很多列表,包含了点【point】、线【polyline】、面【polygon】、标注数据【Annotation】等数据,本次实验我们需要用到的是面数据,也就是.dwgPolygong格式的数据。如下图所示: 把数据加载进来,然后在2处打开属性表,查看CAD数据的属性表,打开后可以发现【layer】图层表示就是地块的用地性质,它就是符号化显示的依据。 我们在数据上右键【属性】,打开图层属性,找到【符号系统】,选择类别中的【唯一值】,然后在【值字段】下拉选择【layer】, 阅读详情

相关推荐

Halcon图片拼接避坑指南:特征点匹配常见问题与解决方案

本文深入解析Halcon图片拼接中特征点匹配的常见问题与解决方案,涵盖特征点提取、匹配优化及变换模型选择等关键环节。针对工业视觉检测中的拼接错位、重影等问题,提供参数调优、图像预处理和算法选择等实战技巧,帮助开发者高效避坑并提升拼接精度。

weixin_28694169的博客 198

C# 设计模式-----单例模式(Singleton)

访问只需要通过,Singlton.Instance 为何称它为单线程的Singlton因为 在多个线程同一时间访问 Instance属性时,首先访问的线程在判断instance为null时则,进入创建对象实例,在创建的过程中,又一个线程对属性进行访问,此时instance还是为null ,所以会同时可能创建多个实例。只需要保证核心是:如何控制用户使用new对一个类的实例构造器的任意调用。如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?,才能确保它们的逻辑正确性、以及良好的效率。

猪猪的博客 714

GD32F103VBT6串口OTA升级保姆级教程:当硬件没留Boot0引脚时,我是如何用Keil和Ymodem搞定的

本文详细介绍了GD32F103VBT6在无Boot0引脚情况下的串口OTA升级方案,通过Keil工程改造和Ymodem协议实现可靠固件更新。文章涵盖Bootloader配置、APP工程调整、Ymodem传输优化等关键步骤,为嵌入式开发者提供了一套完整的解决方案,特别适用于封闭式设备的远程更新需求。

weixin_28744613的博客 183

C#中的Singleton模式

c#中的Singleton模式写在前面实现思路实现方法最简单的实现方法如果多线程乱入?线程安全的单例模式第一次尝试功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表...

君子务本 1995

电力电子技术复习笔记

通常在开关过程前后加入谐振,使开关开通前电压先降到0,关断前电流先降到0,消除开关过程电压、电流的重叠,降低它们的变化率,从而大大减小甚至消除开关损耗。小信号线性化模型的原理:忽略开关频率分量和开关频率谐波分量及其边频分量,建立占空比、输入电压等的低频扰动对变换器中的电压、电流影响的模型。解:可以利用变压器的变比改变输出电压大小,避免控制过程的占空比过小或过大,提高控制精度,同时有利于减轻输出电路中电力电子器件的耐压要求。驱动电路:用于控制功率半导体器件的开关,从而控制电路的电流和电压。

Miracle Fan的博客 1万+

手把手教你用STM32驱动SPL06-001气压传感器(附完整代码与避坑指南)

本文详细介绍了如何使用STM32驱动SPL06-001气压传感器,包括硬件连接、寄存器配置、驱动层实现和数据补偿算法。通过完整的代码示例和避坑指南,帮助开发者快速掌握SPL06传感器的应用技巧,提升嵌入式系统开发效率。

weixin_42552315的博客 290

C# 单例模式(Singleton)

摘要 在我们日常的工作中经常需要在应用程序中保持一个唯一的实例,如:IO处理,数据库操作等,由于这些对象都要占用重要的系统资源,所以我们必须限制这些实例的创建或始终使用一个公用的实例,这就是我们今天要介绍的——单例模式(Singleton)。 使用频率 高 单件模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点...

271

库存预测新思路:AI架构师的图神经网络应用

用图神经网络(GNN)解决传统库存预测的“关联盲区”,让预测从“孤立商品”转向“商品网络”。传统库存预测的痛点分析;GNN的核心概念(图结构、消息传递);GNN在库存预测中的算法原理与代码实战;实际应用场景与未来趋势。背景:用超市老板的烦恼引出传统方法的问题;核心概念:用“商品朋友圈”比喻GNN的图结构和消息传递;算法原理:用数学公式和Mermaid流程图讲清楚GNN的工作流程;实战:用PyTorch Geometric写一个简单的库存预测模型;

AI Python 编程之道的博客 959

C#中单例模式CSingleton

在 C# 中,单例模式是一种设计模式,确保一个类只有一个实例,并提供全局访问点。单例模式常用于需要全局共享某个资源或对象的场景,如数据库连接、日志记录器等。

hdfinder的博客 1414

我爬取了某非法网贷后台系统数据,终于知道什么叫做利滚利滚利滚利了

我爬取了非法贷款的后台网站!

weixin_44042821的博客 2879

YOLO11全网首发优化:卷积魔改创新 | AAAI 2025 | 一种新颖的风车形卷积(PConv)符合微弱小目标的像素高斯空间分布,增强特征提取,显著增加接受野

我们提出了一种新颖的风车形卷积(PConv)作为骨干网络下层标准卷积的替代品。PConv能更好地符合微弱小目标的像素高斯空间分布,增强特征提取,显著增加接受野,且只引入最小的参数增加。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 1973

c#实现singleton

您要在 C# 中构建应用程序。您需要只有一个实例的类,并且需要提供一个用于访问实例的全局访问点。您希望确保您的解决方案高效,并且能够利用 Microsoft? .NET 公共语言运行库功能。您可能还希望确保解决方案是线程安全的。实现策略尽管 Singleton 是一种相对简单的模式,但是存在与具体实现有关的不同权衡因素和选项。下面是一组实现策略,及其优缺点的讨论。Singleton

Ajou's Blog 1807

【Claude】权限被拒绝 (Permission Denied) 全场景排查 — 已解决

权限配置是 Claude Code 安全使用的核心机制。通过合理的 allow/deny 规则、正确的通配符使用、子代理独立配置、定期安全审计,可以在保证安全性的同时不影响开发效率。deny 优先:deny 规则优先级高于 allow,先保护敏感资源通配符精确单层匹配,**递归匹配,Bash(cmd*)允许带参数最小权限:只允许必要的操作,避免Bash(*)等危险规则CI 用 skip:Headless 模式用避免挂起子代理独立:每个子代理单独配置权限,不自动继承保护密钥:deny.env。

一键难忘的博客 3935

C#实现Singleton

您要在 C# 中构建应用程序。您需要只有一个实例的类,并且需要提供一个用于访问实例的全局访问点。您希望确保您的解决方案高效,并且能够利用 Microsoft? .NET 公共语言运行库功能。您可能还希望确保解决方案是线程安全的。 实现策略 尽管 Singleton 是一种相对简单的模式,但是存在与具体实现有关的不同权衡因素和选项。下面是一组实现策略,及其优缺点的讨论。 Singleton Sing

登峰之道(SuperCode) 1778

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

[ZZ]Singleton的五种C#实现

面试的时候经常被问到 singleton 有几种写法,singleton 也是被面试官问得最多的模式之一,因此转载此文。另外,如果您初学设计模式的话,这里有一本不错的电子书,您可以下载回去看看。地址:http://www.cnblogs.com/Files/QuitGame/CSharpDesignPattern.rarImplementing the Singleton Pattern...

168

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

C#实现Singleton模式

C#语言还是比较常见的东西,这里我们主要介绍C#实现Singleton模式,包括介绍C#不支持全局变量,但还是有可能在某个方法的一开始就在堆上创建了一个对象并直到很久以后才使用它。等方面。 C#实现Singleton模式     任何编写过MFC应用的开发人员(不管编写的应用是如何的小)都知道什么是Singleton。Singleton是类的唯一实例。使用MFC时,从CWinApp派生的应用类

wangjingjing1014的专栏 2088

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Singleton设计模式的C#实现

1Singleton模式。Singleton(译为单件或单态)模式是设计模式中比较简单而常用的模式。有些时候在整个应用程序中,会要求某个类有且只有一个实例,这个时候可以采用Singleton模式进行设计。用Singleton模式设计的类不仅能保证在应用中只有一个实例,而且提供了一种非全局变量的方法进行全局访问,称为全局访问点,这样对于没有全局变量概...

weixin_30776273的博客 78
上一篇: 最新职位无刷新滚动效果
下一篇: web services 创建代理类库的方法
sendling
博客等级 码龄20年 36粉丝 98原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值