473,408 Members | 1,749 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,408 software developers and data experts.

How to use events to cross threads?

I have an object that starts a thread to do a "process". One of the steps
inside this thread launches 12 other threads via a Delegate.BeginInvoke to
process. After these 12 threads are launched, the main thread waits. At the
completion of each subthread, the mainthread checks all 12 thread objects to
see if they are done. If they are, raise an event that says we're done.

So, it's kinda like this:

ProcessThread
- Creates a ProcessObject
- ProcessObject Execute creates a list of 12 SubProcessObjects
- Invokes 12 new SubProcessThreads
- SubProcessObject executes
- SubProcessObject sets a "Completed" flag
- The end routine checks the SubProcessObject list to see if all
"Completed" flags
- If so, raise event to main process to continue to next ProcessObject

Problem is, I don't think the pick-up-on-main-thread is really executing on
the main thread. I think it's continuing to process on the newly created
subthread. Since my class has nothing to do with a Control, I don't have
access to InvokeRequired or Invoke. Is there a way ot make sure my
subthreads really complete?

-BKN
Jun 16 '06 #1
15 2586
Using Delegate.BeginInvoke is called "Asynchronous Delegates". Using
asynchronous delegates uses threads from the thread pool. Unless all 12
delegate calls are active (i.e. they haven't completed by the time the other
delegates are called) it's more than likely an asynchronous delegate is
reusing a thread pool thread that was uses by another asynchronous delegate.

If you want to keep track of threads via a Thread object then you don't want
to use thread pool threads.

How are you keeping track of each thread?

Normally, if the continuation of one thread is Dependant on one or more
other threads you would call Thread.Join() for each thread object--something
you can't do with thread pool threads.

--
http://www.peterRitchie.com/
"Bryce K. Nielsen" wrote:
I have an object that starts a thread to do a "process". One of the steps
inside this thread launches 12 other threads via a Delegate.BeginInvoke to
process. After these 12 threads are launched, the main thread waits. At the
completion of each subthread, the mainthread checks all 12 thread objects to
see if they are done. If they are, raise an event that says we're done.

So, it's kinda like this:

ProcessThread
- Creates a ProcessObject
- ProcessObject Execute creates a list of 12 SubProcessObjects
- Invokes 12 new SubProcessThreads
- SubProcessObject executes
- SubProcessObject sets a "Completed" flag
- The end routine checks the SubProcessObject list to see if all
"Completed" flags
- If so, raise event to main process to continue to next ProcessObject

Problem is, I don't think the pick-up-on-main-thread is really executing on
the main thread. I think it's continuing to process on the newly created
subthread. Since my class has nothing to do with a Control, I don't have
access to InvokeRequired or Invoke. Is there a way ot make sure my
subthreads really complete?

-BKN

Jun 17 '06 #2
> How are you keeping track of each thread?

The main process has a list of objects that are associated with each
thread/delegate. In this object is a flag set at the end of the process, and
then the AsyncCallback from the main process checks the list of processes to
see if they're all completed. If they are, continue processing, otherwise do
nothing and wait until it's called again by another completing thread.
Normally, if the continuation of one thread is Dependant on one or more
other threads you would call Thread.Join() for each thread
object--something
you can't do with thread pool threads.


Well, previously I had all my code on the Form executing stuff, so at the
end (after the AsyncCallback was called and all objects.Completed flag was
true) I would call Form.Invoke and this would continue processing back on
the original/Form thread. However, I recently decoupled the main process
from the Form onto it's own Thread object. So, since this object is not a
Control, it has no Invoke() method. So I'm afraid that at the end, the
process is picking up on the last-executed thread, instead of giving control
back to the main process thread.

So Thread.Join() would allow me to pick back up on the main thread?

-BKN
Jun 18 '06 #3
A general rule of thumb: if the concept/method exists in .NET 1.1 then the
callback/event-handler is being called using the background thread. This is
the case for asynchronous delegates, they're called using the background
thread, not the thread that invoked the delegate.

In .NET 2.0 you can use the AsyncOperationManager class to make sure async
callbacks are called using a particular thread.

Even if you call your AsyncCallback on the "main" thread, you're still going
to be in a situation where the thread that instigates the callback is still
technically running when the callback is called. In the case of async
delegates this callback means the method has finished executing; it doesn't
mean the thread has finished executing.

The only way to know if a thread has terminated (without polling) is if you
use Thread.Join, something that you can't use with thread pool threads. In
your case, I don't know why you'd want to make the distinction of when the
task is completed and when the thread has terminated...

Another thing I should point out is when to use multiple threads. There's
really only three reliable scenarios for multiple threads. One scenario is:
you want to spawn a single thread to do work because another thread that does
not use much of the CPU needs to be active. This includes spawning
background threads from a GUI thread to keep the GUI responsive. A second
scenario is if you want to take advantage of multi-processor or
multi-core-processors. The third scenario is you want to wait for something
to complete (like asynchronous IO) without blocking another thread.

If you spawn more than one thread on a single processor, single-core
processor, then you're actually slowing your program down. Your program is
now using more system resources, asking the system to manage your threads
(time-slicing between them, incurring a context switch), and adding
processing to start and wait for the threads. All of which take processing
time.

--
http://www.peterRitchie.com/
"Bryce K. Nielsen" wrote:
How are you keeping track of each thread?


The main process has a list of objects that are associated with each
thread/delegate. In this object is a flag set at the end of the process, and
then the AsyncCallback from the main process checks the list of processes to
see if they're all completed. If they are, continue processing, otherwise do
nothing and wait until it's called again by another completing thread.
Normally, if the continuation of one thread is Dependant on one or more
other threads you would call Thread.Join() for each thread
object--something
you can't do with thread pool threads.


Well, previously I had all my code on the Form executing stuff, so at the
end (after the AsyncCallback was called and all objects.Completed flag was
true) I would call Form.Invoke and this would continue processing back on
the original/Form thread. However, I recently decoupled the main process
from the Form onto it's own Thread object. So, since this object is not a
Control, it has no Invoke() method. So I'm afraid that at the end, the
process is picking up on the last-executed thread, instead of giving control
back to the main process thread.

So Thread.Join() would allow me to pick back up on the main thread?

-BKN

Jun 18 '06 #4
> The only way to know if a thread has terminated (without polling) is if
you
use Thread.Join, something that you can't use with thread pool threads.
In
your case, I don't know why you'd want to make the distinction of when the
task is completed and when the thread has terminated...


That's kind of what I thought, that the "pick up" code is no longer being
executed on the main process thread, but is now executing on the last
completed delegate thread. I guess that's OK, it just didn't seem like the
right way to go and I'd rather code continue back on the original thread. As
mentioned before, I was able to do this when the code was using the Form
thread. But I guess I can't do that now.

-BKN
Jun 19 '06 #5
> Another thing I should point out is when to use multiple threads. There's
really only three reliable scenarios for multiple threads. One scenario
is:
you want to spawn a single thread to do work because another thread that
does
not use much of the CPU needs to be active. This includes spawning
background threads from a GUI thread to keep the GUI responsive. A second
scenario is if you want to take advantage of multi-processor or
multi-core-processors. The third scenario is you want to wait for
something
to complete (like asynchronous IO) without blocking another thread.


That's actually the part of the process that I'm multithreading. The project
is migrating data from one SQL Server to another (and the client was adamant
about not using DTS). There are 12 tables that are being transferred, so I
decided to spawn 12 threads to do this transfer bit. A lot of pre-setup and
post-setup is necessary before and after the transfers, and that happens
synchronously on the main-process-thread. But having the SQL statements run
threaded like this does appear to go quite a bit faster (i.e. while a large
SELECT is running, the short ones are completing).

-BKN
Jun 19 '06 #6
Thread.Join will mean the main thread will block until all threads that have
been used in Thread.Join calls, terminate. Which will do what you want. If
that main thread is doing any GUI work; your program will look unresponsive
(I think you said you abstracted it away from a Form class; so, I assume this
"main" thread is another background thread, which I refer to as the "host"
thread).

I would suggest, if you're using VS2005/.NET2.0, that you use the
BackgroundWorker class. It uses the an updated asynchronous model (via
events, rather than a call back) and manages calling the events (at least the
progress and the completed events) on the thread that started the
asynchronous operation, not the thread that is performing the background
operation.

I don't think you need to worry whether the background thread is still
"alive", just whether it's operation is completed or not. The drawback of
using something like BackgroundWorker, as you've noticed with asynchronous
delegates, is you need some way of managing the state of all those
operations. This could simply be an array of WaitHandles for which a call to
WaitHandle.WaitAll is made in the host thread to tell when all operations
have completed. The BackgroundWorker.RunWorkerCompleted event would simply
signal that WaitHandle object.

--
http://www.peterRitchie.com/
"Peter Ritchie" wrote:
A general rule of thumb: if the concept/method exists in .NET 1.1 then the
callback/event-handler is being called using the background thread. This is
the case for asynchronous delegates, they're called using the background
thread, not the thread that invoked the delegate.

In .NET 2.0 you can use the AsyncOperationManager class to make sure async
callbacks are called using a particular thread.

Even if you call your AsyncCallback on the "main" thread, you're still going
to be in a situation where the thread that instigates the callback is still
technically running when the callback is called. In the case of async
delegates this callback means the method has finished executing; it doesn't
mean the thread has finished executing.

The only way to know if a thread has terminated (without polling) is if you
use Thread.Join, something that you can't use with thread pool threads. In
your case, I don't know why you'd want to make the distinction of when the
task is completed and when the thread has terminated...

Another thing I should point out is when to use multiple threads. There's
really only three reliable scenarios for multiple threads. One scenario is:
you want to spawn a single thread to do work because another thread that does
not use much of the CPU needs to be active. This includes spawning
background threads from a GUI thread to keep the GUI responsive. A second
scenario is if you want to take advantage of multi-processor or
multi-core-processors. The third scenario is you want to wait for something
to complete (like asynchronous IO) without blocking another thread.

If you spawn more than one thread on a single processor, single-core
processor, then you're actually slowing your program down. Your program is
now using more system resources, asking the system to manage your threads
(time-slicing between them, incurring a context switch), and adding
processing to start and wait for the threads. All of which take processing
time.

--
http://www.peterRitchie.com/
"Bryce K. Nielsen" wrote:
How are you keeping track of each thread?


The main process has a list of objects that are associated with each
thread/delegate. In this object is a flag set at the end of the process, and
then the AsyncCallback from the main process checks the list of processes to
see if they're all completed. If they are, continue processing, otherwise do
nothing and wait until it's called again by another completing thread.
Normally, if the continuation of one thread is Dependant on one or more
other threads you would call Thread.Join() for each thread
object--something
you can't do with thread pool threads.


Well, previously I had all my code on the Form executing stuff, so at the
end (after the AsyncCallback was called and all objects.Completed flag was
true) I would call Form.Invoke and this would continue processing back on
the original/Form thread. However, I recently decoupled the main process
from the Form onto it's own Thread object. So, since this object is not a
Control, it has no Invoke() method. So I'm afraid that at the end, the
process is picking up on the last-executed thread, instead of giving control
back to the main process thread.

So Thread.Join() would allow me to pick back up on the main thread?

-BKN

Jun 19 '06 #7
Actually, after a bit of though, you can get the same effect as Thread.Join
with asynchronous delegates with the EndInvoke call. Each BeginInvoke should
be matched with an EndInvoke call anyway. EndInvoke will block (just as
Thread.Join blocks) until the delegate call returns.

--
http://www.peterRitchie.com/
"Peter Ritchie" wrote:
A general rule of thumb: if the concept/method exists in .NET 1.1 then the
callback/event-handler is being called using the background thread. This is
the case for asynchronous delegates, they're called using the background
thread, not the thread that invoked the delegate.

In .NET 2.0 you can use the AsyncOperationManager class to make sure async
callbacks are called using a particular thread.

Even if you call your AsyncCallback on the "main" thread, you're still going
to be in a situation where the thread that instigates the callback is still
technically running when the callback is called. In the case of async
delegates this callback means the method has finished executing; it doesn't
mean the thread has finished executing.

The only way to know if a thread has terminated (without polling) is if you
use Thread.Join, something that you can't use with thread pool threads. In
your case, I don't know why you'd want to make the distinction of when the
task is completed and when the thread has terminated...

Another thing I should point out is when to use multiple threads. There's
really only three reliable scenarios for multiple threads. One scenario is:
you want to spawn a single thread to do work because another thread that does
not use much of the CPU needs to be active. This includes spawning
background threads from a GUI thread to keep the GUI responsive. A second
scenario is if you want to take advantage of multi-processor or
multi-core-processors. The third scenario is you want to wait for something
to complete (like asynchronous IO) without blocking another thread.

If you spawn more than one thread on a single processor, single-core
processor, then you're actually slowing your program down. Your program is
now using more system resources, asking the system to manage your threads
(time-slicing between them, incurring a context switch), and adding
processing to start and wait for the threads. All of which take processing
time.

--
http://www.peterRitchie.com/
"Bryce K. Nielsen" wrote:
How are you keeping track of each thread?


The main process has a list of objects that are associated with each
thread/delegate. In this object is a flag set at the end of the process, and
then the AsyncCallback from the main process checks the list of processes to
see if they're all completed. If they are, continue processing, otherwise do
nothing and wait until it's called again by another completing thread.
Normally, if the continuation of one thread is Dependant on one or more
other threads you would call Thread.Join() for each thread
object--something
you can't do with thread pool threads.


Well, previously I had all my code on the Form executing stuff, so at the
end (after the AsyncCallback was called and all objects.Completed flag was
true) I would call Form.Invoke and this would continue processing back on
the original/Form thread. However, I recently decoupled the main process
from the Form onto it's own Thread object. So, since this object is not a
Control, it has no Invoke() method. So I'm afraid that at the end, the
process is picking up on the last-executed thread, instead of giving control
back to the main process thread.

So Thread.Join() would allow me to pick back up on the main thread?

-BKN

Jun 19 '06 #8
> Actually, after a bit of though, you can get the same effect as
Thread.Join
with asynchronous delegates with the EndInvoke call. Each BeginInvoke
should
be matched with an EndInvoke call anyway. EndInvoke will block (just as
Thread.Join blocks) until the delegate call returns.


I actually am calling EndInvoke, since the delegate returns a boolean value
and the only way to gain access to this value is via EndInvoke. But the
problem remains, the resulting process does not return to the original
thread, but continues on the last delegate's thread. I'm running into an
issue with my original Thread simply not existing anymore and so my
Thread.Suspend is erroring.

So back to my original question, even if I move away from using the thread
pool, how do I have ThreadA pick up when ThreadB stops?

-BKN
Jun 19 '06 #9
"Bryce K. Nielsen" <br***@sysonyx.com> wrote:
Actually, after a bit of though, you can get the same effect as
Thread.Join
with asynchronous delegates with the EndInvoke call. Each BeginInvoke
should
be matched with an EndInvoke call anyway. EndInvoke will block (just as
Thread.Join blocks) until the delegate call returns.


I actually am calling EndInvoke, since the delegate returns a boolean value
and the only way to gain access to this value is via EndInvoke. But the
problem remains, the resulting process does not return to the original
thread, but continues on the last delegate's thread. I'm running into an
issue with my original Thread simply not existing anymore and so my
Thread.Suspend is erroring.

So back to my original question, even if I move away from using the thread
pool, how do I have ThreadA pick up when ThreadB stops?


Sorry for butting in here, Bryce: I'm not certain what exactly you're
after, but how does this look, assuming no UI component, and assuming
..NET 1.1:

---8<---
using System;
using System.Threading;
using System.Windows.Forms;
using System.Collections;

class App
{
class Job
{
TimeSpan _delay;

public Job(TimeSpan delay)
{
_delay = delay;
}

public void Execute()
{
Thread.Sleep(_delay);
Console.WriteLine("Job done ({0})", _delay);
}
}

static void Main(string[] args)
{
ArrayList jobs = new ArrayList();
for (int i = 0; i < 10; ++i)
jobs.Add(new Job(TimeSpan.FromMilliseconds(50 + 50 * i)));

ArrayList threads = new ArrayList();
foreach (Job job in jobs)
{
Thread thread = new Thread(new ThreadStart(job.Execute));
thread.Start();
threads.Add(thread);
}

// Executing in background ...

// Wait for all jobs to finish...
foreach (Thread thread in threads)
thread.Join();

// Done.
Console.WriteLine("All done.");
}
}
--->8---

Alternatively, to alert the UI, how about this (for .NET 2.0):

---8<---
using System;
using System.Threading;
using System.Windows.Forms;

class App
{
static void Main(string[] args)
{
Form form = new Form();
Button start = new Button();
start.Parent = form;
start.Text = "Start";
start.Click += delegate
{
start.Enabled = false;
ThreadPool.QueueUserWorkItem(delegate
{
int runningCount = 10;
using (ManualResetEvent finished =
new ManualResetEvent(false))
{
for (int i = 0; i < 10; ++i)
{
TimeSpan delay =
TimeSpan.FromMilliseconds(50 + 50 * i);
ThreadPool.QueueUserWorkItem(delegate
{
Thread.Sleep(delay);
Console.WriteLine("Job done ({0})", delay);
if (Interlocked.Decrement(ref runningCount) == 0)
finished.Set();
});
}
finished.WaitOne();
Console.WriteLine("All done.");
// Fire an event on the UI thread.
start.Invoke((MethodInvoker) delegate
{
start.Enabled = true;
MessageBox.Show("Done!");
});
}
});
};

Application.Run(form);
}
}
--->8---

-- Barry

--
http://barrkel.blogspot.com/
Jun 19 '06 #10
> ArrayList threads = new ArrayList();
foreach (Job job in jobs)
{
Thread thread = new Thread(new ThreadStart(job.Execute));
thread.Start();
threads.Add(thread);
}

// Executing in background ...

// Wait for all jobs to finish...
foreach (Thread thread in threads)
thread.Join();


I think that's what I was missing. I was trying to figure out if I want to
launch 12 threads how to I join on all 12 in an asynchrnous manner.

This will take some time, changing from the delegate way to the Thread way,
but I'll try that and report back.

-BKN
Jun 19 '06 #11
> I think that's what I was missing. I was trying to figure out if I want to
launch 12 threads how to I join on all 12 in an asynchrnous manner.


Question on this though, if I call Thread.Join(), will the Form's thread be
able to update a flag (allowing the user to cancel the process)?

In other words, I have a button on the Form to cancel the process. Right
now, that sets a flag on the main process object (which in turn sets it on
the 12 dataprocess objects). Each of these threads intermittently checks
this flag, and if it's set, rollback the process. But if I call
Thread.Join() on all 12 threads, will this flag be set, or will it wait
until Thread.Join has come back?

-BKNK
Jun 19 '06 #12
"Bryce K. Nielsen" <br***@sysonyx.com> wrote:
I think that's what I was missing. I was trying to figure out if I want to
launch 12 threads how to I join on all 12 in an asynchrnous manner.

The first bit of code I posted, the one that loops through each thread
and calls Thread.Join(), will block until they're all finished, so the
body of the threads will be asynchronous, but the .Join() calls
themselves will be synchronous (i.e. the loop won't exit until all work
is done).
Question on this though, if I call Thread.Join(), will the Form's thread be
able to update a flag (allowing the user to cancel the process)?

In other words, I have a button on the Form to cancel the process. Right
now, that sets a flag on the main process object (which in turn sets it on
the 12 dataprocess objects). Each of these threads intermittently checks
this flag, and if it's set, rollback the process. But if I call
Thread.Join() on all 12 threads, will this flag be set, or will it wait
until Thread.Join has come back?


Thread.Join() blocks until the delegate passed to the Thread constructor
has returned. If the delegate passed to the Thread constructor exits in
a timely fashion after this flag has been set, it's no different:
Thread.Join() will still only continue after the delegate passed has
exited.

You haven't mentioned whether you're using 1.1 or 2.0. I've assumed the
worst, and here's a more complete sample (with UI) for 1.1:

---8<---
using System;
using System.Threading;
using System.Windows.Forms;
using System.Collections;
using System.ComponentModel;
using System.Drawing;

class App
{
class Job
{
TimeSpan _delay;
bool _cancelled;

public Job(TimeSpan delay)
{
_delay = delay;
}

public void Cancel()
{
_cancelled = true;
}

public void Execute()
{
DateTime finished = DateTime.UtcNow + _delay;
while (DateTime.UtcNow < finished)
{
Thread.Sleep(TimeSpan.FromMilliseconds(1));
if (_cancelled)
{
Console.WriteLine("Job {0} cancelled.", _delay);
return;
}
}
Console.WriteLine("Job done ({0})", _delay);
}
}

class OuterJob
{
ISynchronizeInvoke _invoker;
MethodInvoker _done;
ArrayList _jobs = new ArrayList();

public OuterJob(ISynchronizeInvoke invoker, MethodInvoker done)
{
_invoker = invoker;
_done = done;
}

public void Cancel()
{
lock (_jobs.SyncRoot)
foreach (Job job in _jobs)
job.Cancel();
}

public void Execute()
{
// Collect jobs.
lock (_jobs.SyncRoot)
{
for (int i = 0; i < 10; ++i)
_jobs.Add(
new Job(TimeSpan.FromMilliseconds(50 + 50 * i)));
}

// Start jobs running.
ArrayList threads = new ArrayList();
lock (_jobs.SyncRoot)
{
foreach (Job job in _jobs)
{
Thread thread =
new Thread(new ThreadStart(job.Execute));
thread.Start();
threads.Add(thread);
}
}

// Wait for all to finish.
foreach (Thread thread in threads)
thread.Join();

Console.WriteLine("All done.");
// Notify the UI or whatever.
if (_done != null && _invoker != null)
_invoker.Invoke(_done, null);
}
}

OuterJob _outerJob;
Thread _outerThread;
Form _mainForm;
Button _start;
Button _cancel;

void CancelClick(object sender, EventArgs e)
{
_outerJob.Cancel();
}

void StartClick(object sender, EventArgs e)
{
_start.Enabled = false;
_cancel.Enabled = true;
_outerJob = new OuterJob(_mainForm, new MethodInvoker(Done));
_outerThread = new Thread(new ThreadStart(_outerJob.Execute));
_outerThread.Start();
}

void Done()
{
_cancel.Enabled = false;
_start.Enabled = true;
_outerJob = null;
_outerThread = null;
}

static void Main(string[] args)
{
App app = new App();

app._mainForm = new Form();
app._start = new Button();
app._start.Parent = app._mainForm;
app._start.Text = "Start";
app._start.Click += new EventHandler(app.StartClick);

app._cancel = new Button();
app._cancel.Parent = app._mainForm;
app._cancel.Location = new Point(0, 50);
app._cancel.Text = "Cancel";
app._cancel.Enabled = false;
app._cancel.Click += new EventHandler(app.CancelClick);

Application.Run(app._mainForm);
}
}
-->8---

I wouldn't have gone this far, but I know you from the Delphi newsgroups
;-)

-- Barry

--
http://barrkel.blogspot.com/
Jun 19 '06 #13
Barry Kelly <ba***********@gmail.com> wrote:
ISynchronizeInvoke _invoker;
MethodInvoker _done; // Notify the UI or whatever.
if (_done != null && _invoker != null)
_invoker.Invoke(_done, null);


By the way, there's no error handling in the code I posted. You can use
this pattern (above) to invoke arbitrary code in the context of the UI,
in the case of errors. For example, one could use the same pattern with
a callback for any exceptions that occurred.

-- Barry

--
http://barrkel.blogspot.com/
Jun 19 '06 #14
> You haven't mentioned whether you're using 1.1 or 2.0. I've assumed the
worst, and here's a more complete sample (with UI) for 1.1:

I'm using 2.0, VS2005 C# to be exact.

I've moved away from using the Delegates (which I only used because a friend
of mine swore by them, I shoulda just stuck with the original threading
model to begin with) which I think is doing what I want it to do now. It's
also cleaned up my code a lot.
I wouldn't have gone this far, but I know you from the Delphi newsgroups
;-)


Heh, thanks. You need to stop using _name and start using FName then ;-)

Oh, and I have to say I prefer Delphi's TThread way of doing things a lot
more than DotNets. For some reason being able to encapsulate all my code
inside the "thread" object just feels better.

-BKN
Jun 19 '06 #15
"Bryce K. Nielsen" <br***@sysonyx.com> wrote:
You haven't mentioned whether you're using 1.1 or 2.0. I've assumed the
worst, and here's a more complete sample (with UI) for 1.1:


I'm using 2.0, VS2005 C# to be exact.

I've moved away from using the Delegates (which I only used because a friend
of mine swore by them, I shoulda just stuck with the original threading
model to begin with) which I think is doing what I want it to do now. It's
also cleaned up my code a lot.


It can be easier to work with when you've got explicit objects you can
manipulate. The only problem is resources: you can run out of threads.
Every thread reserves a megabyte of virtual address space or so for its
stack, so you don't need too many threads before you start running into
trouble. That's where the ThreadPool, a synchronization object like
ManualResetEvent, and a little fiddling with Interlocked.* becomes the
better approach - an earlier post of mine used the ThreadPool.
Alternatively, a producer-consumer queue can work, with Semaphores.

Of course, it's possible to get into a deadlock by running out of
ThreadPool threads, but that's a different problem.
I wouldn't have gone this far, but I know you from the Delphi newsgroups
;-)


Heh, thanks. You need to stop using _name and start using FName then ;-)

Oh, and I have to say I prefer Delphi's TThread way of doing things a lot
more than DotNets. For some reason being able to encapsulate all my code
inside the "thread" object just feels better.


And I have to say that I prefer passing an anonymous delegate to
ThreadPool.QueueUserWorkItem()... ;) I lurve anonymous delegates.

If you're nostalgic for TThread, it's easy to create, of course.

-- Barry

--
http://barrkel.blogspot.com/
Jun 19 '06 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

28
by: Dennis Owens | last post by:
I am trying to run a thread off of a form, and every once in a while the thread will raise an event for the form to read. When the form gets the event, the form will place the event into a dataset...
23
by: Jeff Rodriguez | last post by:
Here's what I want do: Have a main daemon which starts up several threads in a Boss-Queue structure. From those threads, I want them all to sit and watch a queue. Once an entry goes into the...
2
by: Wavemaker | last post by:
I have a component class that has a set of events. The class uses a worker thread to do some processing. When it is finished with the processing, it raises the appropriate events. Problem,...
5
by: Richard | last post by:
All, I have a worker thread that fires events across threads to both GUI objects and thread agnostic objects. My code is working but I want to be assured that it did it "the right way"... ...
3
by: daan | last post by:
Hello, I have a problem and I can't get the solution for it :( I have a com dll, which i imported as a reference. The com object is part of a class which is multithreaded and will create...
4
by: | last post by:
I'm looking to understand the way events work across multiple threads. I have an object that needs to process data as it comes in. When a certain threshold is hit, it needs to tell the host...
6
by: DaTurk | last post by:
Here's a quick question, say I have a class with a main routine, we'll just call it main. Main is on the "main" thread. Now lets have main creat an instance of another class, which creates a...
14
by: Gotch | last post by:
Hi all, I've recently digged into C# and the whole .Net stuff. Particularly I found the idea of adding Events and Delegates to the C# language very interesting and I'm trying to use them in...
4
by: jehugaleahsa | last post by:
Hello: Is there a way to prevent one event from firing while another event is already being fired? I have a tool that extracts media from web pages and it has multiple events firing when the...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.