Cross Thread calls

P

Paul Cheetham

Hi,

I have a couple of classes that I am using to read a swipe-card reader
attached to the serial port (c# VS 2005 Pro).
I have a SerialComm class which actaully reads the serial port, and a
CardReader class which validates the number etc.

Neither of these classes inherit from any other classes / controls.

The SerialComm class is instantiated by the Cardreader class, so in the
main code a new CardReader is created, and this creates a SerialComm
class which listens to the serial port.

SerialComm exposes the OnReceiveData event, which is implenented as:
protected void DataAvailable (string DataStr)
// Create an event for data available at the comm port.
// Can be overridden if any special handling is required.
{
if (_Listening)
if(OnReceiveData != null)
OnReceiveData(_Port, DataStr.ToString());
}

This is handled in the CardReader class in this function:
protected void DataReceived(int Port, string DataString)
{ //Data has been received by the Comms object - Validate and
generate event
string CommString;

_CardNumber = "";
if (_Active) //Only react if object is active
{ if (DataString.Length == (_LeadBytes + _CardNumberLength +
EndBytes))
{ CommString = DataString;
if(ValidateCardNumber (CommString))
{ _CardNumber = CommString.Substring(_LeadBytes,
_CardNumberLength);
_Error = 0;
_ErrorString = "";
if (OnCardSwiped != null) OnCardSwiped (this, _Port,
_CardNumber);
} else
if (OnInvalidCardSwiped != null) OnInvalidCardSwiped
(this, _Port, DataString);
} else
{ _Error = errInvalidDataLength;
_ErrorString = "Card number is an invalid length";
if (OnInvalidCardSwiped != null)
OnInvalidCardSwiped (this, _Port, DataString);
}
}
}


Because the SerialComm class uses a new thread to listen to the serial
port, these events fire on that thread, and not the thread that
originally instantiated the objects.

Is there a way of marshalling these calls back to the original thread
within these classes (preferably with the SerialComm class) so that
everything else then works as expected.
I don't want to have to start marshalling on the form that creates the
CardReader object, as I would like these to be self-contained, I they
are used in several projects.


Your suggestions would be much appreciated.

Thankyou

Paul
 
K

Kevin Spencer

Hi Paul,

The thread that creates the new thread can attach an event handler as long
as the object itself is created in that thread. I created a service that
does something similar (not in many ways, but as far as threading). It
creates an instance of an object, wires up event handlers to the object's
events, and then launches a method in that object in a new thread.

--
HTH,

Kevin Spencer
Microsoft MVP
Professional Chicken Salad Alchemist

A lifetime is made up of
Lots of short moments.
 
G

Guest

The simple solution is to add an InvokeRequired check to the beginning of
your event handlers in your Form-derived class (which is suggested for any
publicly available method/property that modifies Form data, never-the-less,
"just in case") then call BeginInvoke to make sure the event handler is
called on the Form's thread.
Another option is use the BackgroundWorker class to create the background
thread uses by the serial class. It's RunWorkerAsync methods use the
AsyncOperationManager class to ensure the ProgressChanged and
RunWorkerCompleted are called on the same thread that called RunWorkerAsync().

The most complex option is to uses AsyncOperationManager yourself...
 
P

Paul Cheetham

Thanks everyone.

I'm really looking for a way to do this in my components, rather than
having to do it in the form if at all possible.

Is it possible to get the source code for the framework components?
Using Delphi or C++ Builder from Borland ou had access to all the
components source, and so when there was a problem like this, you just
found somewhere it was done in the existing components and that gave a
great starting point.


Thanks.

Paul
 

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