Event Driven Code and Thread Control

B

Brad Walton

Hello. First post, but been doing a bit of reading here. I am working on a
project in Java, but decided to switch over to C# after seeing some of the
additional features I can get from C#. One of the big changes I want to make
is event-driven code (rather than the linear flow I had in Java). I have
spent a week or so searching Google, talking to a couple of programming
friends, and just chewing on it in my brain. I think I have an ok handle on
delegates (new to me), but I'm still having some issues and could use some
help to push me along in the right direction.

Here is a quick run-down of the program (well, what I had in mind anyway).
There is a GUI thread, a main processing thread (handles parsing, updating
the objects, etc - this could also been on the GUI thread, but not sure if
that is proper design. This would basically be the worker thread where all
the data is actually manipulated), and 2 input threads (1 socket reading
from another application, and 1 file also reading from that same other
application). Both the input threads will be reading data that will affect
the same objects (although most updates will not be of the same attributes).
I'd like for the 2 input threads to fire events at the main processing
thread when they get information. I'd like for that information to be placed
onto the main processing thread when received by it. I'd also like for this
to happen 'instantly' and not use a queue on a timer check (something I was
doing in the Java linear version).

So that's basically where I'm at with it. I have searched Google for c# info
on 'event-driven code', 'delegate marshal thread', etc to try and put this
all together, but I'm not really finding the answers I need. Most of the
marshal information relates to placing it back onto a UI thread (which could
work, but again not sure if that would be good design), not a specified
thread. And this is where I could really use some help. Can I marshal to a
thread I specify? If so, are there any examples, tutorials, etc?

Any help is greatly appreciated.

Brad
 
C

Cor Ligthert[MVP]

Brad,

Make it yourself easy.

In Microsoft Windows there is a message pump going around.
Those messages can be catched by your application and then it are the
events.

Most of those events are related to UI operations, but they can be as well
come from other places as disk IO or whatever.

In fact is that is basically all there is.

Cor
 
L

Lasse Vågsæther Karlsen

Brad said:
Hello. First post, but been doing a bit of reading here. I am working on
a project in Java, but decided to switch over to C# after seeing some of
the additional features I can get from C#. One of the big changes I want
to make is event-driven code (rather than the linear flow I had in
Java). I have spent a week or so searching Google, talking to a couple
of programming friends, and just chewing on it in my brain. I think I
have an ok handle on delegates (new to me), but I'm still having some
issues and could use some help to push me along in the right direction.

Here is a quick run-down of the program (well, what I had in mind
anyway). There is a GUI thread, a main processing thread (handles
parsing, updating the objects, etc - this could also been on the GUI
thread, but not sure if that is proper design. This would basically be
the worker thread where all the data is actually manipulated), and 2
input threads (1 socket reading from another application, and 1 file
also reading from that same other application). Both the input threads
will be reading data that will affect the same objects (although most
updates will not be of the same attributes). I'd like for the 2 input
threads to fire events at the main processing thread when they get
information. I'd like for that information to be placed onto the main
processing thread when received by it. I'd also like for this to happen
'instantly' and not use a queue on a timer check (something I was doing
in the Java linear version).

So that's basically where I'm at with it. I have searched Google for c#
info on 'event-driven code', 'delegate marshal thread', etc to try and
put this all together, but I'm not really finding the answers I need.
Most of the marshal information relates to placing it back onto a UI
thread (which could work, but again not sure if that would be good
design), not a specified thread. And this is where I could really use
some help. Can I marshal to a thread I specify? If so, are there any
examples, tutorials, etc?

Any help is greatly appreciated.

Brad

Look at Control.Invoke. Basically the method allows you to marshal a
delegate to the main GUI thread handling that control, and execute the
method the delegate refers to as part of the GUI thread.

Basically it does this:

1. SendMessage a message to the GUI thread containing the delegate to
execute (SendMessage returns when the message has been processed)
2. The main GUI thread will at some point (depending on how much else it
is doing) process the message, and will thus call the delegate, when it
returns it will put the result into the message record and "return it"
3. The other thread, waiting on SendMessage will resume executing.

This will of course have the effect of serializing all access to the
data structure you're sending data to, and will execute in the GUI
thread. If you're doing lots of heavy painting, the processing of those
messages might take some time to do (relatively speaking).

Another issue is that if you later on decide to separate out the code to
run without a GUI, you're relying on a piece of code that really needs
that message loop.

Personally I would make a class which was thread-safe and could receive
the data without using messages, in a thread-safe manner. If you need to
update a GUI, use a mechanism which simply posts a message to the GUI
thread, and use a thread-safe read/snapshot mechanism to get data from
the intermediate object.
 
B

Brad Walton

----- Original Message -----
From: "Peter Duniho" <[email protected]>
Newsgroups: microsoft.public.dotnet.languages.csharp
Sent: Sunday, May 18, 2008 4:33 PM
Subject: Re: Event Driven Code and Thread Control

Lasse provided a good summary of a basic strategy. I'd like to point out
though that Java and .NET/C# don't really differ as much as one might
initially think. Java has EventQueue.invokeAndWait() which is very
similar to Control.Invoke(). It also has thread synchronization
mechanisms very similar to those available in .NET (which would be a
better way to implement a producer/consumer queue than using a timer to
inspect a queue on a regular basis).

Not to dissuade you from moving to .NET...if you don't need the
cross-platform capability of Java, I personally find .NET/C# nicer to work
with (especially inasmuch as C# seems to me to be a language that borrows
the best from Java, while avoiding some of the more clunky aspects). But
I don't think the two are as different as you seem to think.

Yeah, but I just want to learn C# too :)
You can marshal to a specific thread. See SynchronizationContext for
example. Alternatively, you could have a thread simply monitor a queue of
delegates and consume any delegates you put in the queue. However, most
of the time you don't really need for a specific piece of code to be
executed on a specific thread. That exists in the GUI API because you're
not in control of the processing loop, and the GUI thread has a LOT of
different things it needs to do.

But normally, you'll dedicate a thread to some specific task, and can
better manage that simply by passing data back and forth between threads,
rather than sending a delegate specifically to a thread for execution.
(Besides, even using SynchronizationContext, you need some sort of
dispatch loop...it's no panacea). With thread synchronization objects,
it's very simple to implement a queue that other threads can add data to
and then signal to the thread that's supposed to process the queue to wake
up and start working on the queue.

Pete

Thanks for the replies guys. I appreciate the help. I have continued
searching for better ways to handle this. My design skills in multi-threaded
apps are beginner level (at best). I have played around with the queue
possibility, but I still am running into the same issue. Just to summarize:

I have 3-4 threads (depending on where the 'worker' should go, either on the
main GUI thread or in its own thread). My hang-up is the objects I will be
updating, from both the GUI and possibly a different thread, will read and
write data to/from the objects variables. So I think I am getting into a
synchronization issue with the accessors and any instance variable
manipulation. I have been looking at this as a possible option:
http://en.csharp-online.net/Buildin...onization_Using_the_Synchronization_Attribute

I have read good and bad things about this approach. But essentially all
attributes in the classes are readable and writeable, most by seperate
threads (if the 'worker' thread is different from the GUI thread). That is
why I wanted to marshal the info to a specific thread, but if it's not the
GUI thread then it doesn't solve this issue if I marshal it, because the
objects instance variables are still accessible from multiple threads.

So, do I need to sync the entire class for this? Am I thinking about this
properly, or missing the big picture?

Thanks again,
Brad
 
B

Brad Walton

Can't say. We don't know enough about what you're actually doing. For
what it's worth, a concise-but-complete code sample can go a VERY long
way. :)

Pete

Here is some additional info. First I made a high-level diagram of the
program: http://www.greatergreen.com/temp/FBDHighLevel.jpg

The blue colored squares represent threads. The green Other Application
represents the app I am connecting to. The Queue is where both input threads
will place new data using a similar design to the one found here (half way
down under More Monitor Methods):
http://www.yoda.arachsys.com/csharp/threads/deadlocks.shtml

The models are updated from both the Queue (which actually leads to a
parser, then to updating), and the GUI. One other note here, is the parser
piece is where some events are fired off based on certain conditions. I also
will have controller classes to handle many of the model's primary
functions, and to fire off other events if necessary. I want this program to
be as event driven as possible.

The GUI mainly 'gets' info from the models and displays it. It will also set
some things though, which can also be set from the input side.

I also included a typical 'model' class:
http://www.greatergreen.com/temp/Admin.cs

Sorry for the confusion. Please let me know if more info is needed. I wasn't
sure what exactly you weren't clear about, but I will provide any additional
info needed. I'm just trying to get myself going in the right direction
here. This is a learning project for me in C# as well as multithreading. And
I greatly appreciate the help!

Brad
 
B

Brad Walton

VERY IMPORTANT: when talking about multi-threaded code, it is _critical_
that you be very clear about what kind of "event" you mean when you use
that word. Unfortunately, Microsoft chose to use the same word to
describe a particular language API that is really not a lot different from
simply calling a method directly, as the word that is used to describe a
particular mechanism of inter-thread communication.

In the current context "event-driven" seems to imply the latter, but it's
hard to know for sure. It would be better if you could be explicit about
whether you're talking about C# delegate-based events, or threading
WaitHandle events (e.g. AutoResetEvent and ManualResetEvent).

I am referring to delegate based events.
For what it's worth, here is a simple producer/consumer implementation I
posted last year:
http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/msg/1777b0073d421296

It's just the sort of test application I proposed above. It doesn't _do_
anything, but it illustrates the basic mechanics.

There's a lengthy introduction I wrote with it, and it's a complete
console application. It's actually a little more complicated than what's
needed for this discussion, as it supports multiple consumers. The main
console thread acts as the producer. But the default configuration is to
run only a single consumer thread, and so with that you should be able to
start getting a feel for how some of this thread synchronization works.

Pete

I will have a look at the test application and try to build one myself. I
have spent so much time trying various ideas, that I feel just as confused
now as when I started the porting of this application to C#. Hopefully this
will help clear up some questions.

I appreciate your time Pete. You've been very helpful!

Brad
 

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