【问题标题】:How can I have a class that acts as a Machine Global Singleton?我怎样才能有一个充当机器全局单例的类?
【发布时间】:2012-12-04 21:08:47
【问题描述】:

我有一个服务在后台运行一组进程的情况。这些进程需要根据需要从 GUI 应用程序启动/停止。问题是正在运行的进程列表保存在旨在监视和控制它们的对象的内存中。此对象位于服务实例上,因此无法从 GUI 应用程序实例访问。我认为我需要将该对象转换为在机器上全局静态的 Singleton,例如 Mutex,以便我可以从 GUI 运行它的方法并让它们影响服务。示例代码如下,这不是我拥有的代码,而是它的简化版本。我对基于 Mutex 的 Singleton 的解决方案或更适合我需求的替代方案感兴趣。

namespace SystemWideSingleton
{
    class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                Console.Write("Count = " + GlobalSingleton.Instance.Count++);
                Console.ReadLine();
            }
        }
    }

    public class GlobalSingleton
    {
        static GlobalSingleton() { }

        private GlobalSingleton()
        {
            Count = 0;
        }

        private static readonly GlobalSingleton _instance = new GlobalSingleton();
        public static GlobalSingleton Instance { get { return _instance; } }

        public int Count { get; set; }
    }
}

我希望上面的代码作为两个控制台应用程序运行,并且每个应用程序共享输出。例如。

Application 1:  Application 2:
--------------  --------------
0               0
1               3
2               4
5               7
6               8

非常感谢任何帮助。

附:我知道现在我从单例中得到的只是它可以在同一个应用程序实例上的线程之间工作。我需要它来跨机器上的实例工作。

【问题讨论】:

  • 没有。那不是它的工作原理。您需要在进程之间进行一些通信。单身人士很糟糕。 GlobalSingleton 就像魔鬼的同义词。
  • 也许您可以使用内置的调度程序从 UI 线程上的不同线程进行调用,并让调度程序将调用排队并为您处理并发。
  • 不会使用 Process.GetProcesses() 并过滤您的进程来解决问题吗?
  • 单身人士经常使用得不好,我意识到应该谨慎使用它们。我已经看过并且希望我能找到一个视频,其中有人,我认为是 Jon Skeet,创建了一个应用程序并使用线程让它与它自己的另一个实例共享信息。这就是我所追求的。是的,在你告诉我我做错之前,我正在寻找一种方法来控制 Windows 服务内存中的对象。我宁愿不设置 WCF 层来这样做,但如果事实证明我必须这样做,那么我必须
  • Baaaaaaaaaaaaaad 的想法,即使你让它工作了,在你进入第二天之前它也将无法维护。将通讯添加到服务中,然后让 GUI 使用它们。想想如果你想让多台机器运行你的东西,你必须做什么......

标签: c# multithreading singleton mutex


【解决方案1】:

抛开这是否是个好主意并专注于实际问题,您可以尝试使用Memory mapped filesmutex 来防止出现竞争情况。

这有点麻烦,但可行。

【讨论】:

  • 虽然我的问题可能无法传达这一点,但我的总体目标是尽可能简单。这就是为什么我不想将 WCF 层拖入其中,但看起来这可能是最佳解决方案。
【解决方案2】:

已向您建议了许多选项。我会选择其中之一。请记住,直接读取另一个进程的内存并不容易 - 这是操作系统和 .NET CLR 强制执行的安全性。你必须遵守规则并正确行事。

也许最快的方法是使用带有文件备份的global mutex(关于the best pattern to use it 的讨论),您可以在其中存储许多活动实例。可以有很多变化:您将此计数器存储在注册表、数据库、XML 文件、文本文件中。

或者您可以将计数器存储在主(服务器)应用程序中,并使用 RPC/WCF/SOAP/REST 等从从属(客户端)查询/更新它。

【讨论】:

    【解决方案3】:

    我想您会发现,对于这个问题没有“神奇的 .NET”解决方案。进程间通信是需要根据您要完成的任务来设计的。

    要访问在其他进程中运行的方法,您需要将这些方法公开给进程间通信通道。您可以使用多种方法来完成此任务,包括 WCF,具体取决于您所需的复杂程度。

    What is the easiest way to do inter process communication in C#?

    编辑:如果您要完成的工作(如您所说)只是为了找出“正在运行的进程列表”,System.Diagnostics.Process.GetProcesses() 可能是最好的方法。您可以直接从系统获取进程句柄,这可能是您无论如何都应该做的。我不明白需要 IPC 或 Mutexes 或任何其他复杂的东西作为替代品。

    【讨论】:

    • 我实际上想要访问在不同进程中运行的类中的某些方法。
    • 是的,那仍然是进程间通信。 stackoverflow.com/questions/1802475/…
    • 您能更好地解释一下您的要求吗?也许重新考虑应用程序的设计是可能的?
    猜你喜欢
    • 1970-01-01
    • 2011-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-24
    • 2023-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多