WPF界面开发-C#单例模式实现 页面数据传输

单例模式(Singleton Pattern)是一种常用的软件设计模式,用于确保一个类仅有一个实例,并提供一个全局访问点来获取这个实例。在C#中,单例模式非常有用,特别是在需要管理共享资源访问(如数据库连接、配置文件读取器等)时。

一、单例模式介绍

实现单例模式的几个关键点:

  1. 私有构造函数:防止外部代码通过new关键字创建类的实例。
  2. 私有静态变量:用于存储类的唯一实例。
  3. 公共静态方法:提供一个全局访问点来获取类的唯一实例,如果实例不存在则创建它。

线程安全的单例模式实现

在多线程环境下,单例模式的实现需要确保线程安全,以防止多个线程同时创建实例。

懒汉式(线程不安全)
public class Singleton  
{  
    private static Singleton instance;  
  
    private Singleton() {}  
  
    public static Singleton Instance  
    {  
        get  
        {  
            if (instance == null)  
            {  
                instance = new Singleton();  
            }  
            return instance;  
        }  
    }  
}

注意:上述实现在多线程环境下是不安全的,因为两个线程可能同时进入if (instance == null)判断,导致创建多个实例。

懒汉式(线程安全,双重检查锁定)
public class Singleton  
{  
    private static volatile Singleton instance;  
    private static readonly object lockObject = new object();  
  
    private Singleton() {}  
  
    public static Singleton Instance  
    {  
        get  
        {  
            if (instance == null)  
            {  
                lock (lockObject)  
                {  
                    if (instance == null)  
                    {  
                        instance = new Singleton();  
                    }  
                }  
            }  
            return instance;  
        }  
    }  
}

注意:使用volatile关键字确保instance变量的读写操作不会被编译器优化,同时使用双重检查锁定(Double-Checked Locking)模式来减少锁的使用,提高效率。

饿汉式
public class Singleton  
{  
    private static readonly Singleton instance = new Singleton();  
  
    private Singleton() {}  
  
    public static Singleton Instance  
    {  
        get  
        {  
            return instance;  
        }  
    }  
}

注意:饿汉式在类加载时就完成了实例的初始化,因此是线程安全的,但它不是懒加载的,可能会浪费资源。

单例模式是一种非常有用的设计模式,但在实现时需要注意线程安全和资源利用的问题。在C#中,可以通过私有构造函数、私有静态变量和公共静态方法来实现单例模式,并根据具体需求选择懒汉式或饿汉式实现方式。

二、例子代码

用双重检查锁定的单例模式示例代码,同时展示如何在两个不同的线程中调用这个单例,一个线程用于不断写入数据,另一个线程用于不断读取并展示数据。

using System;  
using System.Threading;  
  
public class Singleton  
{  
    // 私有静态变量,volatile确保在多个线程中读取时不会被缓存  
    private static volatile Singleton _instance;  
    // 私有构造函数  
    private Singleton()  
    {  
    }  
  
    // 公开的单例访问点  
    public static Singleton Instance  
    {  
        get  
        {  
            if (_instance == null) // 第一次检查  
            {  
                lock (typeof(Singleton)) // 锁定  
                {  
                    if (_instance == null) // 第二次检查  
                    {  
                        _instance = new Singleton();  
                    }  
                }  
            }  
            return _instance;  
        }  
    }  
  
    // 简单的数据成员,用于演示写入和读取  
    public int Counter { get; set; }  
}  
  
class Program  
{  
    static void Main(string[] args)  
    {  
        // 第一个线程:不断写入数据  
        Thread writeThread = new Thread(() =>  
        {  
            while (true)  
            {  
                Singleton singleton = Singleton.Instance;  
                singleton.Counter++;  
                // 为了看到效果,可以添加一些输出或延迟  
                Console.WriteLine($"Write Thread: Counter = {singleton.Counter}");  
                Thread.Sleep(100); // 简单的延迟  
            }  
        });  
  
        // 第二个线程:不断读取并展示数据  
        Thread readThread = new Thread(() =>  
        {  
            while (true)  
            {  
                Singleton singleton = Singleton.Instance;  
                // 读取并展示数据  
                Console.WriteLine($"Read Thread: Counter = {singleton.Counter}");  
                Thread.Sleep(200); // 稍微长一点的延迟,以便看到写入和读取的差异  
            }  
        });  
  
        // 启动两个线程  
        writeThread.Start();  
        readThread.Start();  
  
        // 注意:这里直接退出了主线程,但两个子线程会继续运行  
        // 在实际应用中,你可能需要一种方式来优雅地停止这些线程  
  
        Console.WriteLine("Press any key to exit...");  
        Console.ReadKey();  
    }  
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值