Seeking advice on threading issues
Author |
Message |
Joseph Geret #1 / 25
|
 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 |
|
 |
Grady Werne #2 / 25
|
 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 |
|
 |
Joseph Geret #3 / 25
|
 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 |
|
 |
Joseph Geret #4 / 25
|
 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 |
|
 |
Doug #5 / 25
|
 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 |
|
 |
Mark Pearc #6 / 25
|
 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 |
|
 |
Joseph Geret #7 / 25
|
 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 |
|
 |
Joseph Geret #8 / 25
|
 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 |
|
 |
Mark Pearc #9 / 25
|
 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 |
|
 |
Chad Myer #10 / 25
|
 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... 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 |
|
 |
Mark Pearc #11 / 25
|
 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... 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 |
|
 |
Joseph Geret #12 / 25
|
 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 |
|
 |
Mark Pearc #13 / 25
|
 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 |
|
 |
Joseph Geret #14 / 25
|
 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 |
|
 |
Mark Pearc #15 / 25
|
 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 |
|
|
Page 1 of 2
|
[ 25 post ] |
|
Go to page:
[1]
[2] |
|