Thread Safety with Events

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?VHJlY2l1cw==?=

    Thread Safety with Events

    Hello, Newsgroupians:

    I've yet another question. I have an assembly that provides the interface
    for a scanner. The scanner has a method on it called Read(). The prototype
    is as follows...

    void TheirScannerCla ss.Read();

    To retrieve the information from the scan, I need to add an event to the
    created object. EXA:

    TheirScannerCla ss scanner = new TheirScannerCLa ss();
    scanner.ReadEve nt += new TheirScannerCla ss.ReaderReadEv ent(SomeMethod) ;
    scanner.Read();

    void SomeMethod(Read EventArgs rea)
    {
    MessageBox.Show (rea.Value.ToSt ring());
    }

    So if I executed the above code, the value read would be located in
    ReadEventArgs.

    I am trying to create a wrapper for TheirScannerCla ss, for the assembly
    architecture is pourly designed. If I create my own method called Read(), I
    want the return type to be the ReadEventArgs, which is from the event. For
    instance, I'll create a TheirScannerCla ss as a member of my class. In my
    class I'll also create a method called Read, which will return the value
    read. The question is how can I return the EVENT'S ReadEventArgs for my
    method Read()?

    EXA:

    class MyScannerClass
    {
    TheirScannerCla ss m_scanner;

    public MyScannerClass
    {
    m_scanner = new TheirScannerCla ss;
    m_scanner.ReadE vent += new
    TheirScannerCla ss.ReaderReadEv ent(MyScannerCl ass.ReadEvent);
    }

    public static void ReadEvent(ReadE ventArgs rea)
    {
    ...
    }

    public static void Read

    public string Read()
    {
    m_scanner.Read( );

    // Some how have the event's value return here

    }
    }

    I could probably do this using a class variable, but the problem I'd like to
    tackle is thread safety. How can I ensure that the value in Read() is for
    that specific thread. Thank you, all, for your time and consideration in
    this matter.


    Trecius

  • Pavel Minaev

    #2
    Re: Thread Safety with Events

    On Jul 2, 10:29 pm, Trecius <Trec...@discus sions.microsoft .comwrote:
    Hello, Newsgroupians:
    >
    I've yet another question.  I have an assembly that provides the interface
    for a scanner.  The scanner has a method on it called Read().  The prototype
    is as follows...
    >
    void TheirScannerCla ss.Read();
    >
    To retrieve the information from the scan, I need to add an event to the
    created object.  EXA:
    >
    TheirScannerCla ss scanner = new TheirScannerCLa ss();
    scanner.ReadEve nt += new TheirScannerCla ss.ReaderReadEv ent(SomeMethod) ;
    scanner.Read();
    >
    void SomeMethod(Read EventArgs rea)
    {
      MessageBox.Show (rea.Value.ToSt ring());
    >
    }
    >
    So if I executed the above code, the value read would be located in
    ReadEventArgs.
    >
    I am trying to create a wrapper for TheirScannerCla ss, for the assembly
    architecture is pourly designed.  If I create my own method called Read(), I
    want the return type to be the ReadEventArgs, which is from the event.  For
    instance, I'll create a TheirScannerCla ss as a member of my class.  In my
    class I'll also create a method called Read, which will return the value
    read.  The question is how can I return the EVENT'S ReadEventArgs for my
    method Read()?
    >
    EXA:
    >
    class MyScannerClass
    {
      TheirScannerCla ss m_scanner;
    >
      public MyScannerClass
      {
         m_scanner = new TheirScannerCla ss;
         m_scanner.ReadE vent += new
    TheirScannerCla ss.ReaderReadEv ent(MyScannerCl ass.ReadEvent);
      }
    >
      public static void ReadEvent(ReadE ventArgs rea)
      {
        ...
      }
    >
      public static void Read
    >
      public string Read()
      {
        m_scanner.Read( );
    >
        // Some how have the event's value return here
    >
      }
    >
    }
    >
    I could probably do this using a class variable, but the problem I'd like to
    tackle is thread safety.  How can I ensure that the value in Read() is for
    that specific thread.  Thank you, all, for your time and consideration in
    this matter.
    Consider using anonymous delegates (or lambdas, if you work with
    VS2008) for this:

    class MyScannerClass
    {
    TheirScannerCla ss m_scanner;

    public MyScannerClass
    {
    m_scanner = new TheirScannerCla ss();
    }

    public string Read()
    {
    ReadEventArgs capturedRea;
    Action<ReadEven tArgsreadEventH andler = delegate(ReadEv entArgs
    rea) { capturedRea = rea; }
    m_scanner.ReadE vent += readEventHandle r;
    m_scanner.Read( );
    m_scanner.ReadE vent -= readEventHandle r;

    // Use capturedRea as needed
    ...
    }
    }

    Comment

    • qglyirnyfgfo@mailinator.com

      #3
      Re: Thread Safety with Events

      Hi Pavel:

      Ok, I didn’t test this so most likely I am wrong but here I go :)

      I really like this idea but I am thinking that he may run into
      problems if two or more threads subscribe to the event before any of
      these threads call Read().

      This is because if at one point the ReadEvent has two delegates
      subscribed to it, when the Read() method internally fires the
      ReadEvent, all currently subscribed delegates will receive the
      acknowledgment and that will introduce a bug since only one thread
      will have the right value.

      Also, without being too familiar with this multithreading stuff. The
      OP would have to make sure that the event is implemented correctly, I
      believe that by default if you let the compiler implement the event it
      will be thread safe but if the method was implemented manually then
      the OP will need to verify that the event (subscription, un-
      subscription) are thread safe.

      Assuming that what I said is correct….. then perhaps I would create a
      new instance of the “TheirScannerCl ass” every time Read() method is
      called (inside the method) and leave the rest of the code the way it
      is.



      On Jul 2, 3:58 pm, Pavel Minaev <int...@gmail.c omwrote:
      On Jul 2, 10:29 pm, Trecius <Trec...@discus sions.microsoft .comwrote:
      >
      >
      >
      >
      >
      Hello, Newsgroupians:
      >
      I've yet another question.  I have an assembly that provides the interface
      for a scanner.  The scanner has a method on it called Read().  The prototype
      is as follows...
      >
      void TheirScannerCla ss.Read();
      >
      To retrieve the information from the scan, I need to add an event to the
      created object.  EXA:
      >
      TheirScannerCla ss scanner = new TheirScannerCLa ss();
      scanner.ReadEve nt += new TheirScannerCla ss.ReaderReadEv ent(SomeMethod) ;
      scanner.Read();
      >
      void SomeMethod(Read EventArgs rea)
      {
        MessageBox.Show (rea.Value.ToSt ring());
      >
      }
      >
      So if I executed the above code, the value read would be located in
      ReadEventArgs.
      >
      I am trying to create a wrapper for TheirScannerCla ss, for the assembly
      architecture is pourly designed.  If I create my own method called Read(), I
      want the return type to be the ReadEventArgs, which is from the event.  For
      instance, I'll create a TheirScannerCla ss as a member of my class.  Inmy
      class I'll also create a method called Read, which will return the value
      read.  The question is how can I return the EVENT'S ReadEventArgs for my
      method Read()?
      >
      EXA:
      >
      class MyScannerClass
      {
        TheirScannerCla ss m_scanner;
      >
        public MyScannerClass
        {
           m_scanner = new TheirScannerCla ss;
           m_scanner.ReadE vent += new
      TheirScannerCla ss.ReaderReadEv ent(MyScannerCl ass.ReadEvent);
        }
      >
        public static void ReadEvent(ReadE ventArgs rea)
        {
          ...
        }
      >
        public static void Read
      >
        public string Read()
        {
          m_scanner.Read( );
      >
          // Some how have the event's value return here
      >
        }
      >
      }
      >
      I could probably do this using a class variable, but the problem I'd like to
      tackle is thread safety.  How can I ensure that the value in Read() isfor
      that specific thread.  Thank you, all, for your time and considerationin
      this matter.
      >
      Consider using anonymous delegates (or lambdas, if you work with
      VS2008) for this:
      >
      class MyScannerClass
      {
        TheirScannerCla ss m_scanner;
      >
        public MyScannerClass
        {
           m_scanner = new TheirScannerCla ss();
        }
      >
        public string Read()
        {
           ReadEventArgs capturedRea;
           Action<ReadEven tArgsreadEventH andler = delegate(ReadEv entArgs
      rea) { capturedRea = rea; }
           m_scanner.ReadE vent += readEventHandle r;
           m_scanner.Read( );
           m_scanner.ReadE vent -= readEventHandle r;
      >
           // Use capturedRea as needed
           ...
        }
      >
      >
      >
      }- Hide quoted text -
      >
      - Show quoted text -- Hide quoted text -
      >
      - Show quoted text -

      Comment

      • Peter Duniho

        #4
        Re: Thread Safety with Events

        On Wed, 02 Jul 2008 15:19:56 -0700, <qglyirnyfgfo@m ailinator.comwr ote:
        Hi Pavel:
        >
        Ok, I didn’t test this so most likely I am wrong but here I go :)
        Other than your suggestion to create a new instance of "TheirScannerCl ass"
        for each read, I don't disagree with what you've written, per se. But
        it's not clear to me that these are problems the OP will run into.
        I really like this idea but I am thinking that he may run into
        problems if two or more threads subscribe to the event before any of
        these threads call Read().
        You are correct that Pavel's suggestion assumes that only one Read() will
        be executed while a given event handler is subscribed. However, assuming
        a shared instance of "TheirScannerCl ass", this can be easily handled by
        synchronizing the whole operation (that is, the event subscription, the
        Read(), and the unsubscription) .

        Of course, this is only an issue if the OP has code that may be reading
        from the same instance of "TheirScannerCl ass" from multiple threads. That
        would be a fairly unusual scenario for any type of i/o, so I think it's
        very likely that the OP isn't ever going to run into the potential issue
        in the first place.

        Pete

        Comment

        Working...