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. Thread safety

Thread safety

Scheduled Pinned Locked Moved C#
question
18 Posts 3 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.
  • S scadaguy

    Although the execution of multiple events cannot be performed simultaneously on a single CPU, they can certainly be interlaced since they are executing on separate threads. The usage of synchronization techniques still applies. Furthermore, making assumptions about the hardware and how it relates to thread synchronization is a dangerous road to go down. Brian

    T Offline
    T Offline
    TimK
    wrote on last edited by
    #9

    Thanks for these comments. From the comments made earlier I was starting to think that my understanding of the need for synchronization was completely wrong. Your comments have really cleared things up for me. :)

    1 Reply Last reply
    0
    • T TimK

      Hi, I am trying to get my head around safe thread synchronization. I think the code below is not thread safe as the Start() method may be called several times which would cause the event to be fired asynchronously. Any comments?

      public class ThreadTest1
      {
      public void Start()
      {
      Thread thread = new Thread( new ThreadStart(ThreadMethod));
      thread.Start();
      }

      private void ThreadMethod()
      {
      while (true)
      {
      Thread.Sleep(1000);
      OnEvent(EventArgs.Empty);
      }
      }

      public event EventHandler Event;
      protected virtual void OnEvent(EventArgs e)
      {
      if (Event != null)
      {
      Event(this, e);
      }
      }
      }

      Would the code below be safe? I have wrapped the event code in a locked block.

      public class ThreadTest2
      {
      public void Start()
      {
      Thread thread = new Thread( new ThreadStart(ThreadMethod));
      thread.Start();
      }

      private void ThreadMethod()
      {
      while (true)
      {
      Thread.Sleep(1000);
      DoEvent();
      }
      }

      private void DoEvent()
      {
      lock (this)
      {
      OnEvent(EventArgs.Empty);
      }
      }

      public event EventHandler Event;
      protected virtual void OnEvent(EventArgs e)
      {
      if (Event != null)
      {
      Event(this, e);
      }
      }
      }

      Any comments would be appreciated

      M Offline
      M Offline
      Meysam Mahfouzi
      wrote on last edited by
      #10

      Hummmm, but because of one reason, you may need to use lock in your first example. Consider below situation: A thread(say thread_A) reaches here:

      if (Event != null){
      Event(this, e);
      }

      thread_A checks and sees that Event is not null, and goes to fire Event(this, e). But before calling it, its time slice terminates. Now suppose that in our main application, by using **-=** operator the Event gets null. Now it's thread_A's turn to continue. But an exception will be fired by calling Event(this, e). This will not happen be using below code:

      lock(this){
      if (Event != null){
      Event(this, e);
      }
      }

      I am wondered why below code doesn't lock the Event and the exception would occur:

      lock(Event){
      if (Event != null){
      Event(this, e);
      }
      }


      Don't forget, that's

      Persian Gulf

      not Arabian gulf!

      T S 2 Replies Last reply
      0
      • M Meysam Mahfouzi

        Hummmm, but because of one reason, you may need to use lock in your first example. Consider below situation: A thread(say thread_A) reaches here:

        if (Event != null){
        Event(this, e);
        }

        thread_A checks and sees that Event is not null, and goes to fire Event(this, e). But before calling it, its time slice terminates. Now suppose that in our main application, by using **-=** operator the Event gets null. Now it's thread_A's turn to continue. But an exception will be fired by calling Event(this, e). This will not happen be using below code:

        lock(this){
        if (Event != null){
        Event(this, e);
        }
        }

        I am wondered why below code doesn't lock the Event and the exception would occur:

        lock(Event){
        if (Event != null){
        Event(this, e);
        }
        }


        Don't forget, that's

        Persian Gulf

        not Arabian gulf!

        T Offline
        T Offline
        TimK
        wrote on last edited by
        #11

        Your example is interesting but I think that your suggested solution is flawed. Placing the lock around the event raising code e.g.

        lock(this) {
        if (Event != null) {
        Event(this, e);
        }
        }

        will not stop our main application from using -= operator on the Event. The lock places the event raising code in a critical section. It does not stop other threads accessing the Event property. What do you think?:confused:

        M S 2 Replies Last reply
        0
        • T TimK

          Your example is interesting but I think that your suggested solution is flawed. Placing the lock around the event raising code e.g.

          lock(this) {
          if (Event != null) {
          Event(this, e);
          }
          }

          will not stop our main application from using -= operator on the Event. The lock places the event raising code in a critical section. It does not stop other threads accessing the Event property. What do you think?:confused:

          M Offline
          M Offline
          Meysam Mahfouzi
          wrote on last edited by
          #12

          I don't think;), I tried it and it worked seamlessly!:)


          Don't forget, that's

          Persian Gulf

          not Arabian gulf!

          T S 2 Replies Last reply
          0
          • M Meysam Mahfouzi

            I don't think;), I tried it and it worked seamlessly!:)


            Don't forget, that's

            Persian Gulf

            not Arabian gulf!

            T Offline
            T Offline
            TimK
            wrote on last edited by
            #13

            OK ... How about posting your test code.

            M 1 Reply Last reply
            0
            • M Meysam Mahfouzi

              Hummmm, but because of one reason, you may need to use lock in your first example. Consider below situation: A thread(say thread_A) reaches here:

              if (Event != null){
              Event(this, e);
              }

              thread_A checks and sees that Event is not null, and goes to fire Event(this, e). But before calling it, its time slice terminates. Now suppose that in our main application, by using **-=** operator the Event gets null. Now it's thread_A's turn to continue. But an exception will be fired by calling Event(this, e). This will not happen be using below code:

              lock(this){
              if (Event != null){
              Event(this, e);
              }
              }

              I am wondered why below code doesn't lock the Event and the exception would occur:

              lock(Event){
              if (Event != null){
              Event(this, e);
              }
              }


              Don't forget, that's

              Persian Gulf

              not Arabian gulf!

              S Offline
              S Offline
              scadaguy
              wrote on last edited by
              #14

              I mentioned this problem briefly in my original post. My example code assumes that all event handlers have been added prior to calling ThreadTest.Start(). It's easy is see that unsubscribing with -= will cause a lot of problems after the threads have been started, but += could be problematic as well. This problem is difficult solve correctly and that is why I suggested to intentionally leave the ThreadTest class unsafe for multithreading. Simply locking the code that raises the event is insufficient. You must lock the -= and += operators as well. This can be done with special syntax, using the add and remove keywords.

              public class ThreadTest
              {
              private ArrayList _events = new ArrayList();

              public event EventHandler MyEvent
              {
              add { lock (this) { _events.Add(value); } }
              remove { lock (this) { _events.Remove(value); } }
              }

              public void Start()
              {
              // Same code as before
              }

              private void ThreadMethod()
              {
              while (true)
              {
              ArrayList clone;
              lock (this)
              {
              clone = (ArrayList)_events.Clone();
              }
              foreach (EventHandler e in clone)
              {
              e.DynamicInvoke(...);
              }
              }
              }
              }

              If you're going to do this you might as well make every method on ThreadTest thread-safe to avoid confusion and inconsistency. This solution still requires that subscribers handle their on synchronization. Brian

              1 Reply Last reply
              0
              • M Meysam Mahfouzi

                I don't think;), I tried it and it worked seamlessly!:)


                Don't forget, that's

                Persian Gulf

                not Arabian gulf!

                S Offline
                S Offline
                scadaguy
                wrote on last edited by
                #15

                You were lucky :)

                M 1 Reply Last reply
                0
                • T TimK

                  Your example is interesting but I think that your suggested solution is flawed. Placing the lock around the event raising code e.g.

                  lock(this) {
                  if (Event != null) {
                  Event(this, e);
                  }
                  }

                  will not stop our main application from using -= operator on the Event. The lock places the event raising code in a critical section. It does not stop other threads accessing the Event property. What do you think?:confused:

                  S Offline
                  S Offline
                  scadaguy
                  wrote on last edited by
                  #16

                  TimK wrote: What do you think? You are correct.

                  1 Reply Last reply
                  0
                  • T TimK

                    OK ... How about posting your test code.

                    M Offline
                    M Offline
                    Meysam Mahfouzi
                    wrote on last edited by
                    #17

                    I just need your e-mail to send source code for you.


                    Don't forget, that's

                    Persian Gulf

                    not Arabian gulf!

                    1 Reply Last reply
                    0
                    • S scadaguy

                      You were lucky :)

                      M Offline
                      M Offline
                      Meysam Mahfouzi
                      wrote on last edited by
                      #18

                      Brian Gideon wrote: You were lucky I can post the source code for you and you will see you are more lucky than me after running it and having no exception! ;);P (need for your mail)


                      Don't forget, that's

                      Persian Gulf

                      not Arabian gulf!

                      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