Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Mutex Not Working

Mutex Not Working

Scheduled Pinned Locked Moved C#
helpcsharphtmlcomdata-structures
23 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J jan larsen

    I didn't see it before, but there is only on condition I can think of that would give this output (considered that there really isn't a typo).

    public bool function1()
    {
    Mutex mutex = new Mutex(false, "MyMutex");
    mutex.WaitOne();
    Console.WriteLine("mutex entered");

    //Do work
    // You may be doing something here that throws an exception. If you catch it somewhere
    // and don't print it, then you will get the output you do.

    Console.WriteLine("mutex exiteded");
    mutex.ReleaseMutex();

    return Give_Status;
    }

    "God doesn't play dice" - Albert Einstein "God not only plays dice, He sometimes throws the dices where they cannot be seen" - Niels Bohr

    D Offline
    D Offline
    Dwayner79
    wrote on last edited by
    #14

    To combat this, I wrapped everything into a try catch block. No exceptions thrown. I have changed everything over to the Lock method you suggested. I copied and pasted into the functions and verified no typos. I am at a loss. Thanks for your help. I could post more code if you think it would help. ***************** "We need to apply 21st-century information technology to the health care field. We need to have our medical records put on the I.T." —GW

    J 1 Reply Last reply
    0
    • J jan larsen

      There is one thing that annoys me :-), and that is your use of a member variable as a return value. When doing that, you take on the burden to be sure that access to that variable is synchronized too. It's just a little thing, but add more of that, and you'll soon end up in a situation where you can't figure out why variable x suddenly changes its value. If you have to use a member variable, be sure to declare it volatile. This ensures that the system doesn't use a cached value for performance reasons, but actually reads the value from the object heap. "God doesn't play dice" - Albert Einstein "God not only plays dice, He sometimes throws the dices where they cannot be seen" - Niels Bohr

      D Offline
      D Offline
      Dwayner79
      wrote on last edited by
      #15

      You are right. I will change that to a local variable. The other thing that bothers me about the code (this is not my code... I just get to troubleshoot/fix it) is this use of byteToSend as a member array. The 10 different functions reinitialize the array to the size needed then call sendAndGetData() which actually writes to a controller via the serial port. Instead of passing these values to sendAndGetData, it is a member variable. I have not figured out the best way around this. But that is another story. ***************** "We need to apply 21st-century information technology to the health care field. We need to have our medical records put on the I.T." —GW

      1 Reply Last reply
      0
      • D Dwayner79

        To combat this, I wrapped everything into a try catch block. No exceptions thrown. I have changed everything over to the Lock method you suggested. I copied and pasted into the functions and verified no typos. I am at a loss. Thanks for your help. I could post more code if you think it would help. ***************** "We need to apply 21st-century information technology to the health care field. We need to have our medical records put on the I.T." —GW

        J Offline
        J Offline
        jan larsen
        wrote on last edited by
        #16

        There are some things that you can rely on: 1. Only one thread will have access to code inside the lock block. 2. If you still get output like this:

        entered lock block
        exiting lock block
        entered lock block
        entered lock block

        from code like this:

        public void Foo()
        {
        lock(lockObject)
        {
        Console.WriteLine("entered lock block");

          // Some code
        
          Console.WriteLine("exiting lock block");
        

        }
        }

        Then // Some code must have thrown an exception which was caught and ignored, or logged somewhere else than std output, in the method that invoked Foo(). The only alternative, is that the first WriteLine invocation is placed outside the lock statement. "God doesn't play dice" - Albert Einstein "God not only plays dice, He sometimes throws the dices where they cannot be seen" - Niels Bohr

        D 1 Reply Last reply
        0
        • J jan larsen

          There are some things that you can rely on: 1. Only one thread will have access to code inside the lock block. 2. If you still get output like this:

          entered lock block
          exiting lock block
          entered lock block
          entered lock block

          from code like this:

          public void Foo()
          {
          lock(lockObject)
          {
          Console.WriteLine("entered lock block");

            // Some code
          
            Console.WriteLine("exiting lock block");
          

          }
          }

          Then // Some code must have thrown an exception which was caught and ignored, or logged somewhere else than std output, in the method that invoked Foo(). The only alternative, is that the first WriteLine invocation is placed outside the lock statement. "God doesn't play dice" - Albert Einstein "God not only plays dice, He sometimes throws the dices where they cannot be seen" - Niels Bohr

          D Offline
          D Offline
          Dwayner79
          wrote on last edited by
          #17

          From MSDN: "While a mutual-exclusion lock is held, code executing in the same execution thread can also obtain and release the lock. However, code executing in other threads is blocked from obtaining the lock until the lock is released." This makes it sound like this will only work in multiple threads. A for loop is one thread... is it not. Also, There are two functions being called. Both have to work off the same lock. I tried it with one and it works. I apologize for the confussion. Fromt he original post, I need both functions to work off the same lock. This is what is not working. I can poll the one function (just did 100 times in a row) and it worked fine. when I poll two functions it fails.: for(int i =1; i < 5; i++) { lockedFunction1() lockedFunction2() } What is happening then is this output: Function1 entered Function1 exited Function2 entered Function1 entered Function1 exited Function2 exited (but with an error because value are not right because of mixup. ***************** "We need to apply 21st-century information technology to the health care field. We need to have our medical records put on the I.T." —GW

          D J 2 Replies Last reply
          0
          • D Dwayner79

            From MSDN: "While a mutual-exclusion lock is held, code executing in the same execution thread can also obtain and release the lock. However, code executing in other threads is blocked from obtaining the lock until the lock is released." This makes it sound like this will only work in multiple threads. A for loop is one thread... is it not. Also, There are two functions being called. Both have to work off the same lock. I tried it with one and it works. I apologize for the confussion. Fromt he original post, I need both functions to work off the same lock. This is what is not working. I can poll the one function (just did 100 times in a row) and it worked fine. when I poll two functions it fails.: for(int i =1; i < 5; i++) { lockedFunction1() lockedFunction2() } What is happening then is this output: Function1 entered Function1 exited Function2 entered Function1 entered Function1 exited Function2 exited (but with an error because value are not right because of mixup. ***************** "We need to apply 21st-century information technology to the health care field. We need to have our medical records put on the I.T." —GW

            D Offline
            D Offline
            Dwayner79
            wrote on last edited by
            #18

            My point is if there were an exception, we would never see the second function eventually exit. Sorry that was not very clear. ***************** "We need to apply 21st-century information technology to the health care field. We need to have our medical records put on the I.T." —GW

            1 Reply Last reply
            0
            • D Dwayner79

              From MSDN: "While a mutual-exclusion lock is held, code executing in the same execution thread can also obtain and release the lock. However, code executing in other threads is blocked from obtaining the lock until the lock is released." This makes it sound like this will only work in multiple threads. A for loop is one thread... is it not. Also, There are two functions being called. Both have to work off the same lock. I tried it with one and it works. I apologize for the confussion. Fromt he original post, I need both functions to work off the same lock. This is what is not working. I can poll the one function (just did 100 times in a row) and it worked fine. when I poll two functions it fails.: for(int i =1; i < 5; i++) { lockedFunction1() lockedFunction2() } What is happening then is this output: Function1 entered Function1 exited Function2 entered Function1 entered Function1 exited Function2 exited (but with an error because value are not right because of mixup. ***************** "We need to apply 21st-century information technology to the health care field. We need to have our medical records put on the I.T." —GW

              J Offline
              J Offline
              jan larsen
              wrote on last edited by
              #19

              It's the second method call that's the problem. No mutex, monitor or lock statement can help you here as they are all concerned about threading. But the output clearly says that you're running multithreaded. The lockedFunction2() invocation will not execute before lockedFunction1() is finished. To get the output you display, lockedFunction1(), lockedFunction2() or both must start another thread that outputs the text. To test for this you could make this change to the output routine:

              Console.WriteLine("function 1 entered in thread: " + System.Threading.Thread.CurrentThread.GetHashCode() );

              if the hashcode differs in the output, then it's another thread. If it doesn't, then call an Exorcist :-) "God doesn't play dice" - Albert Einstein "God not only plays dice, He sometimes throws the dices where they cannot be seen" - Niels Bohr

              D 1 Reply Last reply
              0
              • J jan larsen

                It's the second method call that's the problem. No mutex, monitor or lock statement can help you here as they are all concerned about threading. But the output clearly says that you're running multithreaded. The lockedFunction2() invocation will not execute before lockedFunction1() is finished. To get the output you display, lockedFunction1(), lockedFunction2() or both must start another thread that outputs the text. To test for this you could make this change to the output routine:

                Console.WriteLine("function 1 entered in thread: " + System.Threading.Thread.CurrentThread.GetHashCode() );

                if the hashcode differs in the output, then it's another thread. If it doesn't, then call an Exorcist :-) "God doesn't play dice" - Albert Einstein "God not only plays dice, He sometimes throws the dices where they cannot be seen" - Niels Bohr

                D Offline
                D Offline
                Dwayner79
                wrote on last edited by
                #20

                Know any good ones ;) entered commandSetBlockParameter in thread: 20 Exited commandSetBlockParameter in thread: 20 entered queryBlockParameter in thread: 20 entered commandSetBlockParameter in thread: 20 Exited commandSetBlockParameter in thread: 20 entered queryBlockParameter in thread: 20 entered commandSetBlockParameter in thread: 20 Exited commandSetBlockParameter in thread: 20 entered queryBlockParameter in thread: 20 Exited queryBlockParameter in thread: 20 Exited queryBlockParameter in thread: 20 That said, Let me add another issue. This is in a timer loop. The timer was ticking before the last passthrough finished. I can disable the timer until the loop completes than reenable it. This may be the only way to fix this. However, The same problem happens elsewhere when I subscribe to an event and I end up writing two values. I will have to fix this and do more testing. Please do not give up on me. You have been a HUGE help. If I respond in a day, will you be here, or should I start a new thread? Thanks so much... Dwayne ***************** "We need to apply 21st-century information technology to the health care field. We need to have our medical records put on the I.T." —GW

                D J 2 Replies Last reply
                0
                • D Dwayner79

                  Know any good ones ;) entered commandSetBlockParameter in thread: 20 Exited commandSetBlockParameter in thread: 20 entered queryBlockParameter in thread: 20 entered commandSetBlockParameter in thread: 20 Exited commandSetBlockParameter in thread: 20 entered queryBlockParameter in thread: 20 entered commandSetBlockParameter in thread: 20 Exited commandSetBlockParameter in thread: 20 entered queryBlockParameter in thread: 20 Exited queryBlockParameter in thread: 20 Exited queryBlockParameter in thread: 20 That said, Let me add another issue. This is in a timer loop. The timer was ticking before the last passthrough finished. I can disable the timer until the loop completes than reenable it. This may be the only way to fix this. However, The same problem happens elsewhere when I subscribe to an event and I end up writing two values. I will have to fix this and do more testing. Please do not give up on me. You have been a HUGE help. If I respond in a day, will you be here, or should I start a new thread? Thanks so much... Dwayne ***************** "We need to apply 21st-century information technology to the health care field. We need to have our medical records put on the I.T." —GW

                  D Offline
                  D Offline
                  Dwayner79
                  wrote on last edited by
                  #21

                  ok. I have updated the rest of the code and am able to stop it from happening in the timer by disabling it and reenabling it after the loop completes. The same problem still applies to when I subscribe to an event, this launches a new set of code (still in the same thread according to the output) that runs and overlaps. For instance... the original description of two userControls each calling the same communications function. When the user selects the second control it send a stop message to the first control, but that does not stop the form from continuing through it's timer poll. It is in these transitions that the problem still happens. -Dwayne ***************** "We need to apply 21st-century information technology to the health care field. We need to have our medical records put on the I.T." —GW

                  1 Reply Last reply
                  0
                  • D Dwayner79

                    Know any good ones ;) entered commandSetBlockParameter in thread: 20 Exited commandSetBlockParameter in thread: 20 entered queryBlockParameter in thread: 20 entered commandSetBlockParameter in thread: 20 Exited commandSetBlockParameter in thread: 20 entered queryBlockParameter in thread: 20 entered commandSetBlockParameter in thread: 20 Exited commandSetBlockParameter in thread: 20 entered queryBlockParameter in thread: 20 Exited queryBlockParameter in thread: 20 Exited queryBlockParameter in thread: 20 That said, Let me add another issue. This is in a timer loop. The timer was ticking before the last passthrough finished. I can disable the timer until the loop completes than reenable it. This may be the only way to fix this. However, The same problem happens elsewhere when I subscribe to an event and I end up writing two values. I will have to fix this and do more testing. Please do not give up on me. You have been a HUGE help. If I respond in a day, will you be here, or should I start a new thread? Thanks so much... Dwayne ***************** "We need to apply 21st-century information technology to the health care field. We need to have our medical records put on the I.T." —GW

                    J Offline
                    J Offline
                    jan larsen
                    wrote on last edited by
                    #22

                    I'm baffled. I can't imagine how you can possibly get such a result. Look at this, ugly, code:

                    using System;
                    using System.Threading;
                    using System.IO;

                    namespace ConsoleTestApp
                    {
                    public class MyClass
                    {
                    private Timer timer;

                       public static void Main(string\[\] args)
                       {
                       		MyClass myClass = new MyClass();	   		
                       		
                       		using (FileStream fileStream = File.OpenWrite(@"C:\\test.txt"))
                       		{
                       			using (StreamWriter sw = new StreamWriter(fileStream))
                       			{
                       				Console.SetOut(sw);
                       				myClass.Start();
                       				Thread.Sleep(10000);
                       				myClass.Stop();
                       				Thread.Sleep(1000);
                       			}
                       		}
                       }
                       
                       public void Start()
                       {
                       		timer = new Timer( new TimerCallback(MyTimerCallback), null, 0, 500 );
                       }
                       
                       public void Stop()
                       {
                       		timer.Dispose();
                       }
                    
                       private void MyTimerCallback(object state)
                       {
                          for (int i = 0; i < 5; i++)
                          {
                             Foo();
                          }
                       }
                    
                       private void Foo()
                       {
                          lock (this)
                          {
                          	Console.WriteLine("Entered lock block in thread " + Thread.CurrentThread.GetHashCode());
                          	
                          	Thread.Sleep(100);
                          	
                          	Console.WriteLine("Leaving lock block in thread " + Thread.CurrentThread.GetHashCode());
                          }
                       }
                    
                    }
                    

                    }

                    It doesn't produce the outcome you get. Does your code look something like this? "God doesn't play dice" - Albert Einstein "God not only plays dice, He sometimes throws the dices where they cannot be seen" - Niels Bohr

                    D 1 Reply Last reply
                    0
                    • J jan larsen

                      I'm baffled. I can't imagine how you can possibly get such a result. Look at this, ugly, code:

                      using System;
                      using System.Threading;
                      using System.IO;

                      namespace ConsoleTestApp
                      {
                      public class MyClass
                      {
                      private Timer timer;

                         public static void Main(string\[\] args)
                         {
                         		MyClass myClass = new MyClass();	   		
                         		
                         		using (FileStream fileStream = File.OpenWrite(@"C:\\test.txt"))
                         		{
                         			using (StreamWriter sw = new StreamWriter(fileStream))
                         			{
                         				Console.SetOut(sw);
                         				myClass.Start();
                         				Thread.Sleep(10000);
                         				myClass.Stop();
                         				Thread.Sleep(1000);
                         			}
                         		}
                         }
                         
                         public void Start()
                         {
                         		timer = new Timer( new TimerCallback(MyTimerCallback), null, 0, 500 );
                         }
                         
                         public void Stop()
                         {
                         		timer.Dispose();
                         }
                      
                         private void MyTimerCallback(object state)
                         {
                            for (int i = 0; i < 5; i++)
                            {
                               Foo();
                            }
                         }
                      
                         private void Foo()
                         {
                            lock (this)
                            {
                            	Console.WriteLine("Entered lock block in thread " + Thread.CurrentThread.GetHashCode());
                            	
                            	Thread.Sleep(100);
                            	
                            	Console.WriteLine("Leaving lock block in thread " + Thread.CurrentThread.GetHashCode());
                            }
                         }
                      
                      }
                      

                      }

                      It doesn't produce the outcome you get. Does your code look something like this? "God doesn't play dice" - Albert Einstein "God not only plays dice, He sometimes throws the dices where they cannot be seen" - Niels Bohr

                      D Offline
                      D Offline
                      Dwayner79
                      wrote on last edited by
                      #23

                      Not really. It would be more like:

                      using System;
                      using System.Threading;
                      using System.IO;

                      namespace ConsoleTestApp
                      {
                      public class MyClass
                      {
                      private Timer timer;

                         public static void Main(string\[\] args)
                         {
                         		MyClass myClass = new MyClass();	   		
                         		timer.Interval=100;
                         		timer.Enabled=true;
                                          timer.Tick += new System.EventHandler(this.timer\_Tick);
                      
                         }
                         
                         public void timer\_Tick()
                         {
                         		Foo1();
                                          Foo2();
                         }
                         
                      
                         private void Foo1()
                         {
                            lock(LockClass.LOCK\_OBJECT)
                            {
                            	Console.WriteLine("Entered lock block in thread " + Thread.CurrentThread.GetHashCode());
                            	
                            	Thread.Sleep(100);
                            	
                            	Console.WriteLine("Leaving lock block in thread " + Thread.CurrentThread.GetHashCode());
                            }
                         }
                      
                             private void Foo2()
                         {
                            lock(LockClass.LOCK\_OBJECT)
                            {
                            	Console.WriteLine("Entered lock block in thread " + Thread.CurrentThread.GetHashCode());
                            	
                            	Thread.Sleep(200);
                            	
                            	Console.WriteLine("Leaving lock block in thread " + Thread.CurrentThread.GetHashCode());
                            }
                         }
                      
                      }
                      
                      public class LockClass
                      {
                      	public static readonly object LOCK\_OBJECT = new object();
                      }
                      

                      }

                      This was typed so my syntax may not be exact. There is also no start and stop events. this is mainly to let you get the idea. As you can see it takes more time for the Foos to run that it takes for the timer to start the next tick. so the timer ticks and foo1 is started again while foo2 is still running. So instead of this... I am putting the following in the Timer code:

                      public void timer_Tick()
                      {
                      try
                      {
                      timer.enabled = false;
                      Foo1();
                      Foo2();
                      }
                      finally
                      {
                      timer.enabled = true;
                      }
                      }

                      It is a patch, but it works. I am uncertain of the TimerCallBack. I will spend tonight figuring out that. Perhaps I am not using the Timer properly. I must admit, I had/have little experience with the timers. The other problem is when I subscribe to an event:

                      using System;
                      using System.Threading;
                      using System.IO;

                      namespace ConsoleTestApp
                      {
                      public class MyClass
                      {
                      private Timer timer;
                      private bool doStop1;
                      private bool doStop2;

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups