C# DLL 中的单例类可以跨进程共享吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1038111/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can a Singleton Class inside a DLL be shared across processes?
提问by Bobby Cannon
I am creating a custom .net hardware framework that will be used by other programmers to control some hardware. They will add a reference to our DLL to get to our hardware framework. I am in need of a shared class that will be accessed from multiple applications (processes).
我正在创建一个自定义的 .net 硬件框架,其他程序员将使用它来控制某些硬件。他们将添加对我们的 DLL 的引用以访问我们的硬件框架。我需要一个可以从多个应用程序(进程)访问的共享类。
The singleton pattern seems to be what I need but it only works for multiple threads inside your process. I could be completely wrong but here is an example of the C# code I currently have. I can't help to feel that the design is incorrect. I wish I could share more specific information but I can't.
单例模式似乎是我所需要的,但它仅适用于您进程中的多个线程。我可能完全错了,但这是我目前拥有的 C# 代码示例。我不禁觉得设计不正确。我希望我可以分享更具体的信息,但我不能。
- I must stress that I will have no control over the customer application. The solution must be contained inside the framework (DLL) itself.
- 我必须强调,我将无法控制客户应用程序。解决方案必须包含在框架 (DLL) 本身中。
The Framework: (Shared DLL)
框架:(共享DLL)
public class Resources
{
static readonly Resources m_instance = new Resources();
public string Data;
private Resources()
{
Data = DateTime.Now.ToString();
}
public static Resources Instance
{
get
{
return m_instance;
}
}
}
The Test Application: (eventually customer app)
测试应用程序:(最终客户应用程序)
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Press enter to capture the resource!");
Console.ReadLine();
var resources = Resources.Instance;
Console.WriteLine("\r\n{0}: {1}\r\n", Thread.CurrentThread.ManagedThreadId, resources.Data);
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += WorkerDoWork;
worker.RunWorkerAsync();
while (worker.IsBusy)
{
Thread.Sleep(100);
}
Console.WriteLine("Press enter to close the process!");
Console.ReadLine();
}
static void WorkerDoWork(object sender, DoWorkEventArgs e)
{
var resources = Resources.Instance;
Console.WriteLine("\r\n{0}: {1}\r\n", Thread.CurrentThread.ManagedThreadId, resources.Data);
}
}
The first launched application gives an output of:
第一个启动的应用程序提供以下输出:
Press enter to capture the resource!
1: 6/24/2009 8:27:34 AM
3: 6/24/2009 8:27:34 AM
Press enter to close the process!
按回车捕获资源!
1: 2009/6/24 上午 8:27:34
3:2009 年 6 月 24 日上午 8:27:34
按回车键关闭进程!
The second application gives an output of:
第二个应用程序给出了以下输出:
Press enter to capture the resource!
9: 6/24/2009 8:27:35 AM
10: 6/24/2009 8:27:35 AM
Press enter to close the process!
按回车捕获资源!
9: 6/24/2009 上午 8:27:35
10: 6/24/2009 8:27:35 上午
按回车键关闭进程!
Conclusion:
结论:
I would like to see both applications return the same string of the time of the first instantiation of the class.
我希望看到两个应用程序都返回该类第一次实例化时间的相同字符串。
As you can see the singleton works for the multiple thread inside the process but not cross processes. Maybe this can't be done for I can't seem to find any solution.
正如您所看到的,单例适用于进程内的多线程,但不适用于跨进程。也许这无法完成,因为我似乎找不到任何解决方案。
采纳答案by kemiller2002
You cannot use a singleton to sync across applications. Each runs in its own application space, and as a matter of security cannot access memory/objects/etc. from the other without a method of communication (like remoting) To sync the two they would have to remote into a third program.
您不能使用单例在应用程序之间进行同步。每个都在自己的应用程序空间中运行,并且出于安全考虑无法访问内存/对象/等。从另一个没有通信方法(如远程)要同步两者,他们必须远程进入第三个程序。
回答by JaredPar
Yes it is possible to share a singleton amongst several processes. However you will need to take advantage of a technology which supports interprocess communication in order to achieve this result.
是的,可以在多个进程之间共享一个单例。但是,您需要利用支持进程间通信的技术才能实现此结果。
The most popular technologies which allow you to share out your object fairly directly are Remoting and WCF.
允许您相当直接地共享对象的最流行技术是远程处理和 WCF。
Giving an example of sharing a singleton with either of these is beyond the scope of an SO answer. But there are many tutorials on the web for each of these. Googling either technology plus singleton should put you on the right path.
举一个与其中任何一个共享单例的示例超出了 SO 答案的范围。但是在网络上有很多教程可以用于其中的每一个。谷歌搜索任何一种技术加上单例应该会让你走上正确的道路。
回答by AlbertoPL
To add to the Kevin's answer, your constructor for your class Resources should really be made private for it to be a true singleton, otherwise nothing is stopping someone from creating a new instance of the Resources class through the constructor. This doesn't solve your problem, but it does stop one from misusing the Singleton.
要添加到凯文的答案中,您的类 Resources 的构造函数应该真正设为私有,因为它是真正的单例,否则没有什么可以阻止某人通过构造函数创建 Resources 类的新实例。这并不能解决您的问题,但它确实阻止了人们滥用单例。
回答by Groo
Simply calling a singleton property in a different assembly from two different processes will create different instances of that class.
简单地从两个不同的进程调用不同程序集中的单例属性将创建该类的不同实例。
But you can easily share information between processes using .Net Remoting, or fire interprocess events if you only need simple signaling (EventWaitHandle).
但是您可以使用 .Net Remoting在进程之间轻松共享信息,或者如果您只需要简单的信号(EventWaitHandle),则可以触发进程间事件。
[Edit:]To make it look like a Singleton to your callers, you can expose a class which will internally use Remoting to instantiate a singleton, and then return the instance transparently. Here is an example which (I think) does that: http://www.codeproject.com/KB/dotnet/remotingsingleton.aspx
[编辑:]为了使它看起来像您的调用者的单例,您可以公开一个类,该类将在内部使用 Remoting 来实例化单例,然后透明地返回该实例。这是一个(我认为)这样做的示例:http: //www.codeproject.com/KB/dotnet/remotingsingleton.aspx
回答by Shafqat Ahmed
There are ways to do it as mentioned above. But it is clumsy if you use WCF or remoting. Please try interprocess thread sync techniques.
有上面提到的方法。但是,如果您使用 WCF 或远程处理则很笨拙。请尝试进程间线程同步技术。
For more info read the online free e-book on threading
有关更多信息,请阅读有关线程的在线免费电子书
http://www.albahari.com/threading/
http://www.albahari.com/threading/
Specially see the cross process sync constructs here ...
特别在这里看到跨进程同步结构......
http://www.albahari.com/threading/part2.aspx#_Synchronization_Essentials
http://www.albahari.com/threading/part2.aspx#_Synchronization_Essentials