解决方案内跨项目共享Singleton是否可行?问题求助
跨进程共享Singleton不可行的原因及替代方案
为什么你的Singleton在两个项目中会生成新实例?
- Singleton模式的核心是在单个进程的内存空间内保证唯一实例。Remoting Server和WPF应用是两个独立的操作系统进程,每个进程都有自己独立的CLR运行环境和内存区域。
- 当你在两个项目里调用
GetInstance()时,各自进程都会初始化属于自己的CommunicationSingleton静态实例——它们是内存里完全不相关的两个对象,自然没法共享数据。
跨进程共享数据的可行方案
既然Singleton搞不定跨进程共享,得用专门的跨进程通信(IPC)机制来实现两个项目间的数据传递:
1. 利用.NET Remoting本身的特性
你已经在用Remoting Server,直接在服务端维护一个真正的单例对象,让WPF客户端通过Remoting调用这个单例来操作数据就行:
// Remoting Server端的单例服务对象 public class JobService : MarshalByRefObject { private static readonly JobService _instance = new JobService(); private int _jobCount = 0; private List<Job> _jobs = new List<Job>(); private Job _jobInProgress; private JobService() { } public static JobService GetInstance() { return _instance; } public void AddJob(Job job) { lock (_jobs) { _jobs.Add(job); } } public List<Job> GetJobs() { lock (_jobs) { return new List<Job>(_jobs); // 返回副本避免并发问题 } } // 其他方法同理,注意加锁保证线程安全 }
在Remoting配置里注册这个单例服务后,WPF客户端通过Remoting获取的JobService实例,所有操作都会直接作用于服务端的单例对象,这样就能实现数据共享。
2. 其他可选的IPC机制
如果Remoting满足不了需求,还可以选这些方式:
- WCF:比Remoting更现代的分布式通信框架,支持多种绑定方式,能轻松实现跨进程/机器的服务调用。
- 命名管道:适合本地进程间通信,轻量高效。
- 共享内存:适合高性能、大数据量的本地进程通信,但要自己处理同步和数据序列化问题。
- 消息队列:比如MSMQ,适合异步、解耦的场景。
你的Singleton代码的小优化点
顺便提一句,你的Singleton实现有冗余:
- 你已经在静态字段里直接初始化了
instance = new CommunicationSingleton(),所以GetInstance()里的if (instance == null)判断永远不会触发,可以简化成:
public static CommunicationSingleton GetInstance() { return instance; }
如果要实现懒加载的线程安全单例,更推荐用Lazy
public class CommunicationSingleton { private static readonly Lazy<CommunicationSingleton> _lazyInstance = new Lazy<CommunicationSingleton>(() => new CommunicationSingleton()); private CommunicationSingleton() { } public static CommunicationSingleton GetInstance() { return _lazyInstance.Value; } // 其他成员... }
内容的提问来源于stack exchange,提问作者evie
相关产品推荐
相关产品推荐

