0

I have a windows console app which is interrogating a table in a db. The arguments passed into the console app include a connection string and a value found in a specific table in the db. This console app can be fired up at any time.

I'm looking to only allow one process to run for each value in that column. So if process A is started against db A and value B, and then shortly after, process B is started against db A and value B, then process A will do its work, and process B will terminate elegantly(!) because another process is already doing the work it would have done. If process B has a different db or a different value, then it should be allowed to start.

I've been using a mutex to try to achieve this, but I'm still getting multiple processes running when they should've exited elegantly.

Here's an exert from my code as to how I'm creating the mutex:

`    
 private static Mutex _mutex;

 static void Main(string[] args)
 {           
     try
     {                
         var settings = Switches(args);   
         if (settings.TryGetValue("db", out string db))
         {        
             if (TryGetConnection(settings, out string cx))
             {
                 if (settings.TryGetValue("value", out string value))
                 {                                                         
                     var owned = false;
                     // create name for mutex including the db and table value
                     //so that other processes using the same db and table value
                     //will not be able to acquire the mutex and start processing
                     var mutexName = MutexName(cx, value);                      
                     using (_mutex = new Mutex(false, mutexName, out owned))
                     {
                         if (owned)
                         {
                             // wait up to 10 secs to get mutex
                             var mutexAcquired = _mutex.WaitOne(10000);
                             if (mutexAcquired)
                             {
                                 ... do work here

                                 _mutex.ReleaseMutex();
                             }
                             else
                             { 
                                 return;
                             }
                         }
                         else
                         {                          
                             return;
                         }                            
                     }                   
                 }
             }
         }
     }
     catch (Exception ex)
     {
        ...
     }       
}`

Maybe this isn't the best way to achieve what I'm after.

I'd be grateful if someone could steer me in the right direction, either by correcting what I've done or else suggest a better way? Thx

I have tried various suggestions wrt mutexes none of which have stopped a second process with the same parameters from starting

SWo
  • 1
  • 1
  • Check this, it appears the mutex name must start with `Global`: https://stackoverflow.com/questions/229565/what-is-a-good-pattern-for-using-a-global-mutex-in-c/229567 – Magnetron Mar 01 '23 at 12:20
  • To be honest, I'd abstract the issue one layer up into the database even though that is not what you asked for. I'm only proficient in SQL but I think most databases have a feature to lock resources. Maybe thats also something you can check. This would also protect you against directly manipulating databases. – Aaron Mar 01 '23 at 12:42
  • Aaron ...thx ... just to clarify ...so allow the process to interrogate the database and have a table which records process currently running with those values, and if none is running then continue processing - something like that? – SWo Mar 01 '23 at 13:10

0 Answers0