Seeking advice on threading issues 
Author Message
 Seeking advice on threading issues

First of all, can you recommend a good book which comprehensively addresses
threading issues and techniques? Using basic documentation on the subject,
which is covered briefly in C# and the .NET Platform (Troelsen), I have
gotten my program working. Due to the complexities introduced by
multi-threading, I am not confident that it is absolutely bulletproof and
I'd like to do more research on the subject. If you have a good book on the
subject I'd be glad to hear about it.

In the meanwhile, here are a couple of questions.

A coordinator object sets multiple worker objects in motion on different
threads. These worker objects report back to the coordinator via an event.

Q1. What are the practical implications to implementing the event as a
static event vs an instance event? When is the static event more suitable
and when would the instance event be more suitable?

Q2. In either of these cases, should the workers be using locking to ensure
that events are serialized? What happens if worker A raises an event and
while the coordinator is processing that event, worker B raises the same
event? Are these natively serialized? Is serialization necessary or doesn't
it matter?

Thanks for your help,

Joe Geretz



Sat, 14 May 2005 00:44:31 GMT  
 Seeking advice on threading issues
Check out the book "Visual Basic .NET Threading Handbook" by Wrox Press.
It's short and VERY good.  Covers just about every issue you may have.

Sincerely,
Grady Werner
CrystalTech Web Hosting


Quote:
> First of all, can you recommend a good book which comprehensively
addresses
> threading issues and techniques? Using basic documentation on the subject,
> which is covered briefly in C# and the .NET Platform (Troelsen), I have
> gotten my program working. Due to the complexities introduced by
> multi-threading, I am not confident that it is absolutely bulletproof and
> I'd like to do more research on the subject. If you have a good book on
the
> subject I'd be glad to hear about it.

> In the meanwhile, here are a couple of questions.

> A coordinator object sets multiple worker objects in motion on different
> threads. These worker objects report back to the coordinator via an event.

> Q1. What are the practical implications to implementing the event as a
> static event vs an instance event? When is the static event more suitable
> and when would the instance event be more suitable?

> Q2. In either of these cases, should the workers be using locking to
ensure
> that events are serialized? What happens if worker A raises an event and
> while the coordinator is processing that event, worker B raises the same
> event? Are these natively serialized? Is serialization necessary or
doesn't
> it matter?

> Thanks for your help,

> Joe Geretz



Sat, 14 May 2005 01:02:36 GMT  
 Seeking advice on threading issues
Hi Grady,

Thanks for the reply. I just checked this out on Amazon. The contents
abstract which I saw doesn't specifically mention event handling in a
multi-threaded context (although I imagine this is fairly common). Do you
have this book? Is this topic addressed?

Thanks,

- Joe Geretz


Quote:
> Check out the book "Visual Basic .NET Threading Handbook" by Wrox Press.
> It's short and VERY good.  Covers just about every issue you may have.

> Sincerely,
> Grady Werner
> CrystalTech Web Hosting



> > First of all, can you recommend a good book which comprehensively
> addresses
> > threading issues and techniques? Using basic documentation on the
subject,
> > which is covered briefly in C# and the .NET Platform (Troelsen), I have
> > gotten my program working. Due to the complexities introduced by
> > multi-threading, I am not confident that it is absolutely bulletproof
and
> > I'd like to do more research on the subject. If you have a good book on
> the
> > subject I'd be glad to hear about it.

> > In the meanwhile, here are a couple of questions.

> > A coordinator object sets multiple worker objects in motion on different
> > threads. These worker objects report back to the coordinator via an
event.

> > Q1. What are the practical implications to implementing the event as a
> > static event vs an instance event? When is the static event more
suitable
> > and when would the instance event be more suitable?

> > Q2. In either of these cases, should the workers be using locking to
> ensure
> > that events are serialized? What happens if worker A raises an event and
> > while the coordinator is processing that event, worker B raises the same
> > event? Are these natively serialized? Is serialization necessary or
> doesn't
> > it matter?

> > Thanks for your help,

> > Joe Geretz



Sat, 14 May 2005 03:28:06 GMT  
 Seeking advice on threading issues

Quote:
> Q1. What are the practical implications to implementing the event as a
> static event vs an instance event? When is the static event more suitable
> and when would the instance event be more suitable?

Well here's one interesting issue. If the coordinator wires up a method to a
static event of the worker class, and then the coordinator's client drops
its reference and creates a new coordinator class, then the coordinator
better offer a dispose method to unhook the event (and the client better
call it) otherwise, the event is going to be firing multiple times. Without
the disposal, presumably the disconnect would when the discarded
coordinator(s) are GC'd. But who knows when that will occur... :-)

- Joe G. -



Sat, 14 May 2005 03:44:00 GMT  
 Seeking advice on threading issues
Hi Joseph,

Re Q2.  Events are not natively serialized. I would be inclined to lock
common data as needed within the event handler, but this depends on your
application design. If you hold locks for lengthy time periods then
threading becomes a bit pointless. Threading is simple really - you just
need to assume that any common data could be  touched by more than one at a
time. Nothing is threadsafe unless the docs say it is.

Cheers

Doug Forster


Quote:
> First of all, can you recommend a good book which comprehensively
addresses
> threading issues and techniques? Using basic documentation on the subject,
> which is covered briefly in C# and the .NET Platform (Troelsen), I have
> gotten my program working. Due to the complexities introduced by
> multi-threading, I am not confident that it is absolutely bulletproof and
> I'd like to do more research on the subject. If you have a good book on
the
> subject I'd be glad to hear about it.

> In the meanwhile, here are a couple of questions.

> A coordinator object sets multiple worker objects in motion on different
> threads. These worker objects report back to the coordinator via an event.

> Q1. What are the practical implications to implementing the event as a
> static event vs an instance event? When is the static event more suitable
> and when would the instance event be more suitable?

> Q2. In either of these cases, should the workers be using locking to
ensure
> that events are serialized? What happens if worker A raises an event and
> while the coordinator is processing that event, worker B raises the same
> event? Are these natively serialized? Is serialization necessary or
doesn't
> it matter?

> Thanks for your help,

> Joe Geretz



Sat, 14 May 2005 04:23:11 GMT  
 Seeking advice on threading issues
Hi Joe,

I don't quite understand how your scheme is going to work. When an object on
one thread (your worker) raises an event to another object (your
coordinator), the event handler executes on the same thread that the
RaiseEvent occurred in.

Regards,

Mark


First of all, can you recommend a good book which comprehensively addresses
threading issues and techniques? Using basic documentation on the subject,
which is covered briefly in C# and the .NET Platform (Troelsen), I have
gotten my program working. Due to the complexities introduced by
multi-threading, I am not confident that it is absolutely bulletproof and
I'd like to do more research on the subject. If you have a good book on the
subject I'd be glad to hear about it.

In the meanwhile, here are a couple of questions.

A coordinator object sets multiple worker objects in motion on different
threads. These worker objects report back to the coordinator via an event.

Q1. What are the practical implications to implementing the event as a
static event vs an instance event? When is the static event more suitable
and when would the instance event be more suitable?

Q2. In either of these cases, should the workers be using locking to ensure
that events are serialized? What happens if worker A raises an event and
while the coordinator is processing that event, worker B raises the same
event? Are these natively serialized? Is serialization necessary or doesn't
it matter?

Thanks for your help,

Joe Geretz



Sat, 14 May 2005 05:42:50 GMT  
 Seeking advice on threading issues
Hi Mark,

Quote:
> I don't quite understand how your scheme is going to work. When an
> object on one thread (your worker) raises an event to another object
>  (your coordinator), the event handler executes on the same thread
> that the RaiseEvent occurred in.

I'm not a threading expert. Empirically though, I can see that what I'm
doing does work. Isn't this a rather common design pattern, to allow
multiple background threads to raise events to a common controller? Or is it
more common to allow the worker classes to work totally independently until
all work is done?

- Joe Geretz -



Sat, 14 May 2005 06:18:06 GMT  
 Seeking advice on threading issues
Hi again Mark,

Quote:
> > I don't quite understand how your scheme is going to work. When an
> > object on one thread (your worker) raises an event to another object
> >  (your coordinator), the event handler executes on the same thread
> > that the RaiseEvent occurred in.

Is the implication of what you are telling me here, that inside an event
handler I should only be working with local variables and objects?

Thanks,

- Joe Geretz -



Sat, 14 May 2005 06:37:58 GMT  
 Seeking advice on threading issues
Hi Joe,

From what I understand about your scheme, each worker thread raises an event
to its coordinator instance, and the worker thread is running the event
handler code in the coordinator instance. Is this correct?

If so, how does the coordinator thread receive its information from the
worker threads? Does each worker thread update a module-level variable in
the coordinator instance? If so, do you serialize thread access to this
variable to avoid synchronization problems?

My favourite way of implementing this type of notification scheme is by
spawning threads using asynchronous delegates. For an excellent description
of how this works, please see the following link:

(watch for URL wrap!)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfo...
l/winforms07182002.asp

Regards,

Mark


Hi Mark,

Quote:
> I don't quite understand how your scheme is going to work. When an
> object on one thread (your worker) raises an event to another object
>  (your coordinator), the event handler executes on the same thread
> that the RaiseEvent occurred in.

I'm not a threading expert. Empirically though, I can see that what I'm
doing does work. Isn't this a rather common design pattern, to allow
multiple background threads to raise events to a common controller? Or is it
more common to allow the worker classes to work totally independently until
all work is done?

- Joe Geretz -



Sat, 14 May 2005 06:46:48 GMT  
 Seeking advice on threading issues
I think your URL is wrong. It's a cool URL, don't get me wrong.
Especially
since I just ordered one of those new Dell Axim PocketPCs :)

-c


Quote:
> Hi Joe,

> From what I understand about your scheme, each worker thread raises an
event
> to its coordinator instance, and the worker thread is running the
event
> handler code in the coordinator instance. Is this correct?

> If so, how does the coordinator thread receive its information from
the
> worker threads? Does each worker thread update a module-level variable
in
> the coordinator instance? If so, do you serialize thread access to
this
> variable to avoid synchronization problems?

> My favourite way of implementing this type of notification scheme is
by
> spawning threads using asynchronous delegates. For an excellent
description
> of how this works, please see the following link:

> (watch for URL wrap!)

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfo...

- Show quoted text -

Quote:
> l/winforms07182002.asp

> Regards,

> Mark



> Hi Mark,

> > I don't quite understand how your scheme is going to work. When an
> > object on one thread (your worker) raises an event to another object
> >  (your coordinator), the event handler executes on the same thread
> > that the RaiseEvent occurred in.

> I'm not a threading expert. Empirically though, I can see that what
I'm
> doing does work. Isn't this a rather common design pattern, to allow
> multiple background threads to raise events to a common controller? Or
is it
> more common to allow the worker classes to work totally independently
until
> all work is done?

> - Joe Geretz -



Sat, 14 May 2005 08:41:45 GMT  
 Seeking advice on threading issues
Hi Chad,

Ooops, you're right - sorry about that. Corrected below, but watch for URL
wrap.

Regards,

Mark

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfo...
l/winforms06112002.asp?frame=true


I think your URL is wrong. It's a cool URL, don't get me wrong.
Especially
since I just ordered one of those new Dell Axim PocketPCs :)

-c


Quote:
> Hi Joe,

> From what I understand about your scheme, each worker thread raises an
event
> to its coordinator instance, and the worker thread is running the
event
> handler code in the coordinator instance. Is this correct?

> If so, how does the coordinator thread receive its information from
the
> worker threads? Does each worker thread update a module-level variable
in
> the coordinator instance? If so, do you serialize thread access to
this
> variable to avoid synchronization problems?

> My favourite way of implementing this type of notification scheme is
by
> spawning threads using asynchronous delegates. For an excellent
description
> of how this works, please see the following link:

> (watch for URL wrap!)

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfo...

- Show quoted text -

Quote:
> l/winforms07182002.asp

> Regards,

> Mark



> Hi Mark,

> > I don't quite understand how your scheme is going to work. When an
> > object on one thread (your worker) raises an event to another object
> >  (your coordinator), the event handler executes on the same thread
> > that the RaiseEvent occurred in.

> I'm not a threading expert. Empirically though, I can see that what
I'm
> doing does work. Isn't this a rather common design pattern, to allow
> multiple background threads to raise events to a common controller? Or
is it
> more common to allow the worker classes to work totally independently
until
> all work is done?

> - Joe Geretz -



Sat, 14 May 2005 07:11:53 GMT  
 Seeking advice on threading issues
Hi Mark,

Quote:
> From what I understand about your scheme, each worker thread raises an
event
> to its coordinator instance, and the worker thread is running the event
> handler code in the coordinator instance. Is this correct?

The UI instantiates a single coordinator instance and starts the coordinator
method running on a separate thread. (This keeps the UI responsive.) This
single coordinator instantiates multiple workers and starts each instance's
worker method on a new thread. So this typically involves about 6 threads (1
coordinator + 5 workers) in addition to the UI thread.

Quote:
> If so, how does the coordinator thread receive its information from the
> worker threads?

The coordinator hooks its event handler into a static event defined in the
worker class.

internal delegate void LinkEvent(object o, LinkEventArgs e);
internal static event LinkEvent Link;

Each worker fires the event as follows:

Link(this, new LinkEventArgs(m_ID, AbsLink));

The coordinator hooks into this event as follows:

Worker.Link += new Worker.LinkEvent(zWorkerLink);

(Worker is the type, not an instance. Remember the event is defined as
static.)

When this event fires the handler in the coordinator, the LinkEventArgs
object contains the relevant information.

Quote:
> Does each worker thread update a module-level variable in
> the coordinator instance? If so, do you serialize thread access to this
> variable to avoid synchronization problems?

Yes, the events do modify local variables. Here's an example. (It's a
different event which fires when the worker is done, but it's pattern is
exactly the same as the examples which I supplied above.)

private void zWorkerDone(object o, DoneEventArgs e)
{
    // A worker is reporting done. Available for reassignment, Sir!
    m_FreePtr ++;
    m_Free[m_FreePtr] = e.ID;

Quote:
}

Does this need to be serialized? I guess, huh? How do I do this, via a
lock(this) block?

Other events don't modify local variables but they do use a module level
utility class instance in order to perform some database updates:

private void zWorkerLink(object o, LinkEventArgs e)
{
    m_QueueMgr.Push(e.URL);

Quote:
}

So the object reference is not modified, but conceivable this class might be
swapped between two different events/threads at the same time? I do
occasionally see flaky behavior internal to the m_QueueMgr instance. I
suppose there are one of two ways to address this. Either I place a lock()
block around this statement, or create a local QueueMgr class instance
inside each event.

Thanks for the link, and for any additional suggestions you can offer.

- Joe Geretz -



Sat, 14 May 2005 07:23:22 GMT  
 Seeking advice on threading issues
Hi Joe,

Sorry - as Chad pointed out, wrong URL - here's the correct one (watch for
URL wrap).

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfo...
l/winforms06112002.asp?frame=true

If your event handler code is running on a worker thread, and that thread
modifies module-level variables in your coordinator instance, you do need to
be very careful about synchronization. Remember that thread interleaving
happens not at the source code level, or even at CIL level, but at assembly
code level. Without adequate locking, very strange things can happen. If you
use SyncLock (VB), accessing module-level variables is no longer a
synchronization problem, although then (depending on your scheme) you may
need to start worrying about thread deadlocks.

If the event handler code works only with local variables, you're safe
because they go out of scope as soon as the event handler completes. But
then how does your coordinator thread get access to the results from the
worker threads?

Regards,

Mark


Hi again Mark,

Quote:
> > I don't quite understand how your scheme is going to work. When an
> > object on one thread (your worker) raises an event to another object
> >  (your coordinator), the event handler executes on the same thread
> > that the RaiseEvent occurred in.

Is the implication of what you are telling me here, that inside an event
handler I should only be working with local variables and objects?

Thanks,

- Joe Geretz -



Sat, 14 May 2005 07:21:33 GMT  
 Seeking advice on threading issues
Yes, it's the next article down.

Quote:
> Ooops, you're right - sorry about that. Corrected below, but watch for URL
> wrap.

BTW: How difficult can it be to add a 'Copy URL' option to the Windows Shell
context menu? This is such a common annoyance, you'd think that OE would
provide this by now. Basically, all that's needed is to strip out the line
breaks on the copy. If any one can give me some pointers to the relevant
documentation I'd like to give this a shot.

- Joe Geretz -



Sat, 14 May 2005 07:28:36 GMT  
 Seeking advice on threading issues
Hi Joe,

Quote:
>> Does this need to be serialized? I guess, huh? <<

Yes, definitely.

Quote:
>> How do I do this, via a lock(this) block? <<

No, no, no <smack hand>. A lock locks an object, not a piece of code. Think
of the object being locked as a door to the other threads. If you lock(this)
rather than lock(object), you're opening the door to every other thread. In
this case, you should lock both m_FreePtr and m_Free.

Quote:
>> Either I place a lock() block around this statement, or create a local

QueueMgr class instance inside each event. <<

Yes, I think either way would work (remembering the lock is on the object,
not the statement. Leaving the module-level variable unprotected is a
definite no-no.

Regards,

Mark


Hi Mark,

Quote:
> From what I understand about your scheme, each worker thread raises an
event
> to its coordinator instance, and the worker thread is running the event
> handler code in the coordinator instance. Is this correct?

The UI instantiates a single coordinator instance and starts the coordinator
method running on a separate thread. (This keeps the UI responsive.) This
single coordinator instantiates multiple workers and starts each instance's
worker method on a new thread. So this typically involves about 6 threads (1
coordinator + 5 workers) in addition to the UI thread.

Quote:
> If so, how does the coordinator thread receive its information from the
> worker threads?

The coordinator hooks its event handler into a static event defined in the
worker class.

internal delegate void LinkEvent(object o, LinkEventArgs e);
internal static event LinkEvent Link;

Each worker fires the event as follows:

Link(this, new LinkEventArgs(m_ID, AbsLink));

The coordinator hooks into this event as follows:

Worker.Link += new Worker.LinkEvent(zWorkerLink);

(Worker is the type, not an instance. Remember the event is defined as
static.)

When this event fires the handler in the coordinator, the LinkEventArgs
object contains the relevant information.

Quote:
> Does each worker thread update a module-level variable in
> the coordinator instance? If so, do you serialize thread access to this
> variable to avoid synchronization problems?

Yes, the events do modify local variables. Here's an example. (It's a
different event which fires when the worker is done, but it's pattern is
exactly the same as the examples which I supplied above.)

private void zWorkerDone(object o, DoneEventArgs e)
{
    // A worker is reporting done. Available for reassignment, Sir!
    m_FreePtr ++;
    m_Free[m_FreePtr] = e.ID;

Quote:
}

Does this need to be serialized? I guess, huh? How do I do this, via a
lock(this) block?

Other events don't modify local variables but they do use a module level
utility class instance in order to perform some database updates:

private void zWorkerLink(object o, LinkEventArgs e)
{
    m_QueueMgr.Push(e.URL);

Quote:
}

So the object reference is not modified, but conceivable this class might be
swapped between two different events/threads at the same time? I do
occasionally see flaky behavior internal to the m_QueueMgr instance. I
suppose there are one of two ways to address this. Either I place a lock()
block around this statement, or create a local QueueMgr class instance
inside each event.

Thanks for the link, and for any additional suggestions you can offer.

- Joe Geretz -



Sat, 14 May 2005 07:56:11 GMT  
 
 [ 25 post ]  Go to page: [1] [2]

 Relevant Pages 

1. "Modular programming" advice sought

2. General Design Question- Advice sought.

3. Seeking advice about looping code in VB.

4. Seeking Advice on Outlook Development

5. Seeking advice

6. Seeks Advice on VBA Literature.

7. Seeking advice on searching a string backwards

8. Creating an ADO VB6 stand-alone database program (Newbie seeks advice)

9. Seeking advice on best approach

10. App Data: Seeking Advice

11. Seeking advice on DB access methods

12. Advice sought on implementation of data access

 

 
Powered by phpBB® Forum Software