ThreadStart and ThreadPool

F

Franz

ThreadStart accepts a delegate which doesn't need a parameter, while
ThreadPool.QueueUserWorkItem accpets a WaitCallBack which accpets a object
parameter. Why does the design go different? Does it deal with the concept
of Thread Pool?
Please forgive my silly question.
 
J

Jon Skeet [C# MVP]

Franz said:
ThreadStart accepts a delegate which doesn't need a parameter, while
ThreadPool.QueueUserWorkItem accpets a WaitCallBack which accpets a object
parameter. Why does the design go different? Does it deal with the concept
of Thread Pool?
Please forgive my silly question.

I think it's just an anomaly - and it's certainly not a silly question.
All of the ways of invoking execution on the thread pool take an
object, which is often used for storing whatever EndXXX is going to be
called on (apart from anything else).

It would often be rather handy if ThreadStart took an object parameter
too, frankly...
 
F

Franz

Jon Skeet said:
I think it's just an anomaly - and it's certainly not a silly question.
All of the ways of invoking execution on the thread pool take an
object, which is often used for storing whatever EndXXX is going to be
called on (apart from anything else).

It would often be rather handy if ThreadStart took an object parameter
too, frankly...

Thanks.
I hope the next version of the .NET Framework can give an extra option for
the delegate accepted by ThreadStart.
Do you think it is possible?
 
W

William Stacey [MVP]

I think it has to do with any new thread having just an entry point and not
also a parm. Note that when using ThreadStart, your starting a new thread.
The thread pool already starts its own threads, so internally, it used
ThreadStart too. It uses that thread to call your delegate. You could do
the same kind of thing in your threads by calling other delegates and
passing objects, etc. I agree that that would be handy. If you need state
like this, create an object and contain your new thread inside it and your
worker method as private method. You then can have any state in your object
set by constructors or properties/fields. hth
 
J

Jon Skeet [C# MVP]

William Stacey said:
I think it has to do with any new thread having just an entry point and not
also a parm.

But there's no reason why the framework shouldn't create the new thread
*and* pass it a parameter.
Note that when using ThreadStart, your starting a new thread.
The thread pool already starts its own threads, so internally, it used
ThreadStart too. It uses that thread to call your delegate. You could do
the same kind of thing in your threads by calling other delegates and
passing objects, etc. I agree that that would be handy. If you need state
like this, create an object and contain your new thread inside it and your
worker method as private method. You then can have any state in your object
set by constructors or properties/fields. hth

Yes - but it's more of a pain to do that.
 
J

Jon Skeet [C# MVP]

Franz said:
Thanks.
I hope the next version of the .NET Framework can give an extra option for
the delegate accepted by ThreadStart.
Do you think it is possible?

I think it's unlikely - but things get easier in C# at least, due to
anonymous methods. You'll be able to do things like:

string name, occupation;

ThreadStart starter = new ThreadStart()
{
RealMethod(name, occupation);
};
new Thread(starter).Start();
 
F

Franz

Jon Skeet said:
I think it's unlikely - but things get easier in C# at least, due to
anonymous methods. You'll be able to do things like:

string name, occupation;

ThreadStart starter = new ThreadStart()
{
RealMethod(name, occupation);
};
new Thread(starter).Start();

I nearly forget this techniques. This skill helps a lot.
 
J

Jon Skeet [C# MVP]

Franz said:
I nearly forget this techniques. This skill helps a lot.

I should have been clearer: things *will* get easier in C# v2. You
can't use the above in the currently released version of C#.
 
F

Franz

Jon Skeet said:
I should have been clearer: things *will* get easier in C# v2. You
can't use the above in the currently released version of C#.

Oh.....I may mix up with other language.
 
W

William Stacey [MVP]

But there's no reason why the framework shouldn't create the new thread
*and* pass it a parameter.

One would think this is possible. However I wonder that if it was easy, why
they do not add it. The win32 CreateThread method takes a pointer to a
variable that is passed to thread. I suspect something has to do with
managed/native issues, however the Thread abstration should be able to
handle this I would think.
Yes - but it's more of a pain to do that.

Pain or pattern? I say pattern. Creating a new thread in your program is
not a small design issue for your program. It should be handled with care.
It is not hard to create a new class and gives you better OO design. This
is better IMO, as you can create Stop and Start methods on your threads and
abstract your workers as an object. Different stokes I guess.
 
J

Jon Skeet [C# MVP]

William Stacey said:
Pain or pattern? I say pattern. Creating a new thread in your program is
not a small design issue for your program. It should be handled with care.
It is not hard to create a new class and gives you better OO design. This
is better IMO, as you can create Stop and Start methods on your threads and
abstract your workers as an object. Different stokes I guess.

But sometimes the type you wish to pass as state isn't the type you
wish to "start". You may already have an existing object which contains
all the relevant state needed *except* one variant part, which you'd
like to pass in. You end up having to create an object which just takes
that variant part and the worker part, and has a method which just
calls a method in the real "worker" object with the variant part as a
parameter.
 
A

Alvin Bruney [MVP]

ThreadStart starter = new ThreadStart()
{
RealMethod(name, occupation);
};
new Thread(starter).Start();

what is the point of this? Why does it make coding any easier? what *problem
does it solve?
 
J

Jon Skeet [C# MVP]

what is the point of this? Why does it make coding any easier? what *problem
does it solve?

It solves the problem of not being able to pass parameters to a new
thread, without having to have a separate class just for the state you
would pass as parameters if you could.
 
C

Chris Mullins

what is the point of this? Why does it make coding any easier?
what *problem does it solve?

On several occasions I have had to create classes to hold thread state, when
passing in an object parameter - such as the ThreadPool accepts - would have
been much easier.

Even something as simple as having 10 threads, and having each thread know
what number it is, is difficult without being able to pass in a parameter.
(Ok, well, perhaps not _difficult_ per se, but more difficult than it should
be). This is something many of my multi-threaded stress test cases do.

It just seems like a silly oversight.

It's not as annoying as the omission of WaitHandle.Wait(timeout) overload,
but it's pretty annoying.
 
A

Alvin Bruney [MVP]

Yes, that's pretty neat. Where did that originate? i don't believe i came
across that in my c++ career. is that a java type thing? (cus i'm against it
if it is from java :) i'm kidding.
 
W

William Stacey [MVP]

Same object. Just add an overload in your Start() method to pass the right
object. Either way, your ThreadStart method still needs to know what object
to reference. This can is still simple to do with a class.
 
J

Jon Skeet [C# MVP]

William Stacey said:
Same object. Just add an overload in your Start() method to pass the right
object. Either way, your ThreadStart method still needs to know what object
to reference. This can is still simple to do with a class.

But it can easily bend the design out of shape. If it's so pointless
being able to pass a parameter, why is it available for BeginInvoke
etc? In my view, it often makes things *much* more convenient.
 
J

Jon Skeet [C# MVP]

Yes, that's pretty neat. Where did that originate? i don't believe i came
across that in my c++ career. is that a java type thing? (cus i'm against it
if it is from java :) i'm kidding.

It's similar to Java's anonymous classes, but I think it's restricted
to delegates in C# v2, which is fair enough.
 
W

William Stacey [MVP]

But it can easily bend the design out of shape.

Not that I can see.
If it's so pointless

Never said it was. I agreed it would be good to have.
being able to pass a parameter, why is it available for BeginInvoke
etc?

Same reason it works in the thread pool. BeginInvoke uses a thread pool
thread to run the delegate IIRC. However the thread was created already so
it can call any delegate with args as normal.
In my view, it often makes things *much* more convenient.

I don't see it more convenient then your anonymous example. You then need
to create another delegate.
 
J

John Saunders

Jon Skeet said:
But it can easily bend the design out of shape. If it's so pointless
being able to pass a parameter, why is it available for BeginInvoke
etc? In my view, it often makes things *much* more convenient.

How often have you wanted to pass only a single object as a parameter? That
is, a single object which is not an inherent part of the processing to be
performed by the thread?

I've never found it a burden to place all the state in the class which
contains the thread's ThreadStart method. It has always created a cleaner
design.

BTW, you can set the Name property of a thread after creating it in order to
tell it which number it is.
 

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

Top