Thread Safety with Events

T

Trecius

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 TheirScannerClass.Read();

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

TheirScannerClass scanner = new TheirScannerCLass();
scanner.ReadEvent += new TheirScannerClass.ReaderReadEvent(SomeMethod);
scanner.Read();

void SomeMethod(ReadEventArgs rea)
{
MessageBox.Show(rea.Value.ToString());
}

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

I am trying to create a wrapper for TheirScannerClass, 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 TheirScannerClass 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
{
TheirScannerClass m_scanner;

public MyScannerClass
{
m_scanner = new TheirScannerClass;
m_scanner.ReadEvent += new
TheirScannerClass.ReaderReadEvent(MyScannerClass.ReadEvent);
}

public static void ReadEvent(ReadEventArgs 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
 
P

Pavel Minaev

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 TheirScannerClass.Read();

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

TheirScannerClass scanner = new TheirScannerCLass();
scanner.ReadEvent += new TheirScannerClass.ReaderReadEvent(SomeMethod);
scanner.Read();

void SomeMethod(ReadEventArgs rea)
{
  MessageBox.Show(rea.Value.ToString());

}

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

I am trying to create a wrapper for TheirScannerClass, 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 TheirScannerClass 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
{
  TheirScannerClass m_scanner;

  public MyScannerClass
  {
     m_scanner = new TheirScannerClass;
     m_scanner.ReadEvent += new
TheirScannerClass.ReaderReadEvent(MyScannerClass.ReadEvent);
  }

  public static void ReadEvent(ReadEventArgs 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
{
TheirScannerClass m_scanner;

public MyScannerClass
{
m_scanner = new TheirScannerClass();
}

public string Read()
{
ReadEventArgs capturedRea;
Action<ReadEventArgs> readEventHandler = delegate(ReadEventArgs
rea) { capturedRea = rea; }
m_scanner.ReadEvent += readEventHandler;
m_scanner.Read();
m_scanner.ReadEvent -= readEventHandler;

// Use capturedRea as needed
...
}
}
 
Q

qglyirnyfgfo

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 “TheirScannerClass” every time Read() method is
called (inside the method) and leave the rest of the code the way it
is.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top