1

I have a situation where a service is running a set of processes in the background. Those processes need to be started/stopped from a GUI application on demand. The issue is that the list of running processes is held in memory on an object that is designed to monitor and control them. This object is on the services instance and so not accessible from the GUI applications instance. What I think I need is to turn that object into a Singleton that is Globally static on the machine, like a Mutex, so that I can run it's methods from the GUI and have them affect the service. Example code is below, this is not the code I have but a much simplified version of it. I am interested in A solution to the Mutex based Singleton or an alternative that would suit my needs better.

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; }
    }
}

I would expect the above code to run as two console applications and for each application to share the output. ex.

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

Any help would be very much appreciated.

P.S. I know that right now all I get out of the singleton is that it will work between threads on the same application instance. I need it to work across instances on the machine.

ClaytonHunt
  • 533
  • 1
  • 7
  • 19
  • 4
    No. Thats not how it works. You need some communication between processes. And singletons are bad. GlobalSingleton is like synonym for devil. – Euphoric Dec 17 '12 at 18:24
  • perhaps you can use the built in dispatcher to make calls from the different threads on the UI thread, and let the dispatcher queue the calls and handle the concurrence for you. – dutzu Dec 17 '12 at 18:27
  • wouldn't using Process.GetProcesses() and filtering your processes do the trick? – rony l Dec 17 '12 at 18:31
  • Singletons are often poorly used and I realize that they should be used sparingly. I have seen, and wish I could find, a video where someone, I think it was Jon Skeet, created an app and using threading got it to share information with another instance of it's self. That is what I am after. Yes, before you tell me I'm doing it wrong, again, I am looking for a way to control an object that is in memory on a windows service. I would prefer not setting up a WCF layer to do so, but if it turns out I must then I must – ClaytonHunt Dec 17 '12 at 18:35
  • 1
    Baaaaaaaaaaaaaad idea, even if you got it working it would be unmaintainable before you got in the next day. Add comms to the service, then have the GUI use them. Think about what you'd have to do if you wanted to have multiple machines running your thingies... – Tony Hopkinson Dec 17 '12 at 18:36
  • Doesn't have to Be WCF, could be a file, a database, a registry entry, shudder. WCF is probably easier though, given it's on your network. – Tony Hopkinson Dec 17 '12 at 18:38
  • "The issue is that the list of running processes is held in memory on an object that is designed to monitor and control them. This object is on the services instance and so not accessible from the GUI applications instance." <-- This does not make sense to me; if the GUI is starting and stopping the processes, why doesn't it know which ones are running? – theMayer Dec 17 '12 at 18:59
  • You already know the answer: wcf. If you think maintaining a global singleton is easier than solving it through wcf, think again – Casper Leon Nielsen Jan 04 '13 at 17:24

3 Answers3

0

Putting whether it's a good idea aside and concentrating on the actual question, you could try using Memory mapped files, together with a mutex to prevent race conditions.

It would be somewhat cumbersome, but doable.

rony l
  • 5,798
  • 5
  • 35
  • 56
  • While my question may not convey this, my overall goal is to keep this as simple as possible. That is why I would prefer not to drag a WCF layer into this but it looks like that might be the optimal solution. – ClaytonHunt Dec 17 '12 at 18:58
0

I think what you are going to find is that there is no "magic .NET" solution to this problem. Inter-process communication is something that needs to be designed based on what you are trying to accomplish.

To access methods that are running in other processes, you will need to expose those methods to inter-process communication channels. There are a variety of methods you can use to accomplish this, including WCF, depending on the degree of complexity that you require.

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

Edit: If what you are trying to accomplish is (as you say it is) just to figure out "a list of running processes", System.Diagnostics.Process.GetProcesses() is probably the best way to do this. You can get process handles directly from the system, which is probably what you should be doing anyway. I don't understand the need for IPC or Mutexes or any of this other complicated stuff as an alternative.

Community
  • 1
  • 1
theMayer
  • 15,456
  • 7
  • 58
  • 90
  • I actually want access to certain methods that are in a class that is running in a different process. – ClaytonHunt Dec 17 '12 at 19:09
  • Yes, that is still inter-process communication. http://stackoverflow.com/questions/1802475/what-is-the-easiest-way-to-do-inter-process-communication-in-c – theMayer Dec 17 '12 at 19:11
  • Would you be able to explain your requirements a little bit better? Maybe rethinking the design of the application is possible? – theMayer Dec 17 '12 at 22:05
0

A number of options have been suggested to you. I would choose one of those. Please keep in mind that it is not easy to directly read memory of another process - it is OS and .NET CLR enforced security. You have to obey the rules and play right.

Perhaps the quickest way to do this is to use a global mutex (discussion on the best pattern to use it) backed up with a file, where you store a number of active instances. There can be many variations: you store this counter in the registry, a database, XML file, text file.

Or you can store a counter in a master (server) application and query/update it from slaves (clients) using RPC/WCF/SOAP/REST etc.

Community
  • 1
  • 1
oleksii
  • 35,458
  • 16
  • 93
  • 163