From: Hector Santos on 1 Jun 2010 15:55 For the longest, for my non-I/O based thread work, I used WaitForMultiObjects (WFMO) as a way to wait for a set of worker threads to complete, simpling by putting the thread handles in an array and passing it to WFMO, for example: // Wait (infinitely) for 10 threads to ALL complete. HANDLE hThreads[10] = {0}; for(int i=0; i<10; i++) { hThreads[i] = CreateThread(.......); } WFMO(hThreads,10,TRUE,INFINITE); I wish to do the same in C#, I can start the threads, but I don't see a simple WFMO() idea. Ideally, I wish to have a callback version of WFMO() so that an event is called (i.e. a OnThreadsFinish() event) signally when all threads are finished. Note: I was able to come up with a method, but it seems there is a more natural way in .NET. What I do is: 1) Create X BackgroundWorkers and put it into an array Workers[] 2) Then have a DoEvents loop: int done = 0; while (done < X) { done = 0; for (int i=0; i < X; i++) { if (!Workers[i].IsBusy) done++; } Application.DoEvents(); } // THREADS WE DONE - do whatever I only used a Thread Pool. But I don't see a function there to determine when all the queued threads are complete. Thanks -- HLS
From: Tom Shelton on 1 Jun 2010 16:07 Hector Santos wrote : > For the longest, for my non-I/O based thread work, I used WaitForMultiObjects > (WFMO) as a way to wait for a set of worker threads to complete, simpling by > putting the thread handles in an array and passing it to WFMO, for example: > > // Wait (infinitely) for 10 threads to ALL complete. > > HANDLE hThreads[10] = {0}; > > for(int i=0; i<10; i++) { > hThreads[i] = CreateThread(.......); > } > > WFMO(hThreads,10,TRUE,INFINITE); > > I wish to do the same in C#, I can start the threads, but I don't see a > simple WFMO() idea. > > Ideally, I wish to have a callback version of WFMO() so that an event is > called (i.e. a OnThreadsFinish() event) signally when all threads are > finished. > > Note: I was able to come up with a method, but it seems there is a more > natural way in .NET. What I do is: > > 1) Create X BackgroundWorkers and put it into an array Workers[] > > 2) Then have a DoEvents loop: > > int done = 0; > while (done < X) > { > done = 0; > for (int i=0; i < X; i++) { > if (!Workers[i].IsBusy) done++; > } > Application.DoEvents(); > } > > // THREADS WE DONE - do whatever > > I only used a Thread Pool. But I don't see a function there to determine > when all the queued threads are complete. > > Thanks I think you might be lookign for hte WaitHandle.WaitAll method? -- Tom Shelton
From: Hector Santos on 1 Jun 2010 17:15 Tom Shelton wrote: >> I only used a Thread Pool. But I don't see a function there to >> determine when all the queued threads are complete. >> >> Thanks > > I think you might be lookign for hte WaitHandle.WaitAll method? Yes, thanks tom. I had missed it somehow in MSDN jumping all over the place and got side tracked with MSDN examples with a MSDN comment regarding "multi-tasking" behavior on single vs multi-processor/core machines. I have to pencil that and go over that before I complete my work. But I had finally found it at this "Threading in C#" web site with excellent summary background information for people like me. All concepts consolidated right at the top! BOOK MARK IT! :) http://www.albahari.com/threading/part3.aspx MSDN threading pages also has some needed background information regarding performance. What I ended up doing is writing a class that spawns the dynamically allocated workers with an additional optional thread to monitor the completion and fire an OnMultiThreadComplete event. The default is to just wait in the calling thread with a function that does the loop I showed in my last post. That works nicely as well. BTW, I found the ultimate MSDN Online Help GUI - CHROME!!! IE is just too slow and it is superior with the "smart auto search" as you type. Seems like GOOGLE indexed the entire MSDN content! Check it out! Honestly, it isn't so bad now. THe IDE help simply sucks. But with CHROME it is so fast that its like the old VC6 MSDN but better because the #1 problem there was not being able to open many help page instances. Any way, thats a different topic. :) -- Coming soon, WCLEX - Wildcat! Live Exchange! HLS
From: Tom Shelton on 1 Jun 2010 18:27 Hector Santos wrote on 6/1/2010 : > Tom Shelton wrote: > >>> I only used a Thread Pool. But I don't see a function there to determine >>> when all the queued threads are complete. >>> >>> Thanks >> >> I think you might be lookign for hte WaitHandle.WaitAll method? > > > Yes, thanks tom. I had missed it somehow in MSDN jumping all over the place > and got side tracked with MSDN examples with a MSDN comment regarding > "multi-tasking" behavior on single vs multi-processor/core machines. I have > to pencil that and go over that before I complete my work. > > But I had finally found it at this "Threading in C#" web site with excellent > summary background information for people like me. All concepts consolidated > right at the top! BOOK MARK IT! :) > > http://www.albahari.com/threading/part3.aspx > > MSDN threading pages also has some needed background information regarding > performance. > > What I ended up doing is writing a class that spawns the dynamically > allocated workers with an additional optional thread to monitor the > completion and fire an OnMultiThreadComplete event. The default is to just > wait in the calling thread with a function that does the loop I showed in my > last post. That works nicely as well. > > BTW, I found the ultimate MSDN Online Help GUI - CHROME!!! IE is just too > slow and it is superior with the "smart auto search" as you type. Seems like > GOOGLE indexed the entire MSDN content! Check it out! Honestly, it isn't so > bad now. THe IDE help simply sucks. But with CHROME it is so fast that its > like the old VC6 MSDN but better because the #1 problem there was not being > able to open many help page instances. Any way, thats a different topic. :) > > > -- Coming soon, WCLEX - Wildcat! Live Exchange! > HLS I'm glad you got it worked out. As for using Chrome - no thanks. I'll stick to firefox. May not be as fast, but IMHO, Google is the current evil empire :) -- Tom Shelton
From: Peter Duniho on 2 Jun 2010 01:28 Tom Shelton wrote: > Hector Santos wrote : >> For the longest, for my non-I/O based thread work, I used >> WaitForMultiObjects (WFMO) as a way to wait for a set of worker >> threads to complete, simpling by putting the thread handles in an >> array and passing it to WFMO, for example: >> >> // Wait (infinitely) for 10 threads to ALL complete. >> >> HANDLE hThreads[10] = {0}; >> >> for(int i=0; i<10; i++) { >> hThreads[i] = CreateThread(.......); >> } >> >> WFMO(hThreads,10,TRUE,INFINITE); >> >> I wish to do the same in C#, I can start the threads, but I don't see >> a simple WFMO() idea. >> >> [...] > > I think you might be lookign for hte WaitHandle.WaitAll method? Hector probably would think that's the right equivalent to what he's used to. However, IMHO it is a good idea to get used to using the .NET-native threading and synchronization techniques where applicable. In this particular example, this means a few things: • Don't block the GUI thread. In other words, the very design idea of waiting on all the worker threads is fundamentally flawed. • Use the features built into BackgroundWorker to track and respond to changes in the active thread count. • In other cases, use the Monitor class for cross-thread signaling. The first two points go together, in that using the BackgroundWorker correctly means that the GUI thread does not wind up blocked. Here's an example: void RunWorkers(int count) { for (int i = 0; i < count; i++) { BackgroundWorker worker = new BackgroundWorker(); int delay = i * 500; worker.DoWork += (sender, e) => { // dummy work Thread.Sleep(delay); }; worker.RunWorkerCompleted += (sender, e) => { // Signal completion if (--count == 0) { AllWorkersDone(); } }; worker.RunWorkerAsync(); } } void AllWorkersDone() { // do whatever here } Note that the above assumes RunWorkers() is being called on the main GUI thread. Which means that each RunWorkerCompleted event handler is also executed on the main GUI thread. This has a couple of useful effects: • The "count" variable, used directly in RunWorkers() and as a captured variable in the RunWorkerCompleted event handlers, is only ever used in a single thread, ensuring synchronization. • The AllWorkersDone() method itself will be executed on the main GUI thread, just as if the original method had gotten stuck in a loop waiting for the threads to complete. Of course, the big difference being that the main GUI thread doesn't wind up blocked as in the original implementation. Pete
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: appropriate class variable usage? Next: Must declare the scalar variable "@myDB@" |