Asynchronous event

S

Sin Jeong-hun

Hi.
I want to raise an event in the worker thread to let the UI display
the status, but I do not block the operation itself. The following
codes are just to illustrate the situation, not the real codes.

class Logic
{
public MyEventHandler MyEvent;
public void Start()
{
Thread t = new Thread(new ThreadStart(Work));
t.Start();
}
void Work()
{
while(true)
{
Process one item
MyEvent(this, number of items processed); <---- Line A
}
}
}

class Consumer
{
void Consumer
{
Logic l = new Logic();
l.MyEvent += new MyEventHandler(DoSomeCalc);
}
void DoSomeCalc(....)
{
doing lengthy stupid operations....
}
}
The Work() thread seems to be blocked at Line A if the event consumer
does not return soon. If I am the writer of the UI and it's a Windows
Form, I could use Form's BeginInvoke so that it return will soon, but
I want to make the Line A would work like so no matter how the event
consumer is coded. Was my explination enough? Basically, I just want
to signal others with MyEvent then continue to loop, not to be blocked
by the event consumer at Line A.

What is the best practice for this case? Thanks for any advice.
 
R

RealCat

Hi.
I want to raise an event in the worker thread to let the UI display
the status, but I do not block the operation itself. The following
codes are just to illustrate the situation, not the real codes.

class Logic
{
    public MyEventHandler MyEvent;
    public void Start()
    {
      Thread t = new Thread(new ThreadStart(Work));
      t.Start();
    }
    void Work()
    {
      while(true)
      {
        Process one item
        MyEvent(this, number of items processed); <---- Line A
      }
    }

}

class Consumer
{
   void Consumer
  {
    Logic l = new Logic();
    l.MyEvent += new MyEventHandler(DoSomeCalc);
  }
  void DoSomeCalc(....)
  {
    doing lengthy stupid operations....
  }}

The Work() thread seems to be blocked at Line A if the event consumer
does not return soon. If I am the writer of the UI and it's a Windows
Form, I could use Form's BeginInvoke so that it return will soon, but
I want to make the Line A would work like so no matter how the event
consumer is coded. Was my explination enough? Basically, I just want
to signal others with MyEvent then continue to loop, not to be blocked
by the event consumer at Line A.

What is the best practice for this case? Thanks for any advice.

In short, as an analogy, I want PostMessage, not SendMessage.
 
P

Peter Duniho

[...]
The Work() thread seems to be blocked at Line A if the event consumer
does not return soon. If I am the writer of the UI and it's a Windows
Form, I could use Form's BeginInvoke so that it return will soon, but
I want to make the Line A would work like so no matter how the event
consumer is coded. Was my explination enough? Basically, I just want
to signal others with MyEvent then continue to loop, not to be blocked
by the event consumer at Line A.

What is the best practice for this case? Thanks for any advice.

In short, as an analogy, I want PostMessage, not SendMessage.

Actually, no...you don't really want that. You neither have a SendMessage
paradigm here in the first place, nor do you really want a PostMessage
instead. Either approach would imply that "DoSomeCalc()" gets executed on
the main GUI thread, which of course if you have a main GUI thread is
definitely not what you'd want.

As far as the answer goes, the general approach would be for your MyEvent
handler to execute the actual code in a different thread (just not the
main GUI thread). Since it's the Consumer class that (presumably) knows
of this requirement, that's where you should put the thread invocation
code. There are a variety of ways to do it, but one of the simplest would
be to use the ThreadPool.QueueUserWorkItem() method. An alternative, but
near-equivalent, method would be to use the Delegate.BeginInvoke() method
(it's autogenerated by the compiler for any delegate type).

Again, I would put that invocation in the DoSomeCalc() method itself. You
could instead put it where you raise the event in your Logic class, but
then the Logic class winds up mandating a threaded invocation of the event
handler in _all_ situations, requiring all client code to properly deal
with inter-thread communication issues even if there's no real need for
the threaded behavior. IMHO that's a maintenance hassle that should be
left to the client code to decide, rather than being forced upon each
client regardless.

Pete
 

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

Similar Threads

How can these lines be rewritten 15
Raising and event 3
When is an event null? 22
Use of event handling 6
Event Subscription. Why? 8
Delegates/events 8
Handling Events in C#.NET 5
struggling with events 4

Top