Jade Burton wrote:
> 
> But what's wrong with creating a thread?  If you use the
> threadpool it's almost a one-liner!

Although if you use the threadpool you almost certainly won't be
creating a thread - you'll just be using a thread that was already in
the thread pool most of the time.

And that's typically a good thing of course.  You positively don't want
to create a thread just to perform a single operation.

However, in this case it's possible that you'd want to make an
exception.  The original poster is talking about something that will
take several minutes to execute.  It wasn't clear how many such
operations might be proceeding in parallel.  If it's a large number,
then the thread pool is probably a less good choice because of the upper
limit imposed on the number of threads (25 per CPU by default).  In this
case creating a thread manually *might* be more appropriate.  (On the
other hand, if you're doing something to the database that's taking 10
minutes, you might not want more than 25 such operations running
concurrently!)



> Even if I don't care about the result of the call

This was something that worried me about the original post.  Would you
*really* not care about the result?  Even if the result was "Network
error attempting to contact database", or "Deadlock detected" or
"Constraints violated"?

You may not care about the results of the query, but that's not the same
thing as not caring whether it runs at all.  (If you genuinely don't
care whether the stored procedure runs or not, then I can suggest an
optimization:  don't bother to call the stored procedure.)



> I generally do not use async APIs because I like to be
> responsible for the lifetime of the threads in my app
> (or have that option in the future.)

...and again you won't be responsible for the lifetime of the threads if
you use the threadpool, but that's typically a good thing.

But there's something worth pointing out here.  Some async APIs don't
use threads at all.  For example, using async socket IO doesn't tie up
threads for the duration of the operation.  (The underlying model used
for IO operations inside the OS does *not* require a thread to be sat
around waiting for an operation to complete - it's all essentially
asynchronous.  In fact the synchronous APIs for doing IO in Win32 all
simply kick off an async operation and then put the thread to sleep
until the operation completes.)

So it's possible to kick off, say, 100 concurrent socket operations
using only a single thread.  For example you could do a whole bunch of
async reads in quick succession.  The only point at which the OS
actually needs to get a thread involved is when some data arrives and it
needs to complete the async operation.

By contrast, if you try to do 100 concurrent reads using the approach
you're advocating (i.e. using the synchronous APIs), then you're going
to have problems.  If you use the thread pool, then unless you have 4 or
more processors, you won't manage to get 100 running concurrently, due
to the 25 threads per CPU limit.  You could reconfigure that limit, or
fire up 100 threads by hand, but that's a bad idea - it's not a scalable
approach.

But it is possible for a process to have hundreds of pending
asynchronous reads without needing hundreds of threads.  For example,
imagine a server which has hundreds of clients, most of which are idle
most of the time.  If you use async operations, you only need as many
threads as are required to handle the clients that are currently causing
active work on the server.  But if you require one thread for each read
operation, you're going to hit unnecessary scalability limits because
you just can't have all that many threads...


Unfortunately, ADO.NET is entirely synchronous, so you don't in fact
have this option here.  The only choice is to do stuff on other threads
as has been described by several in this discussion, either firing them
up manually, or using the thread pool.  I just wanted to point out that
in general, it's not necessarily a good idea to prefer synchronous APIs
over asynchronous ones - the OS driver model is inherently asynchronous,
and you may well be paying a bunch of unnecessary extra costs if you opt
for the apparent simplicity of the synchronous API.


-- 
Ian Griffiths
DevelopMentor

===================================
This list is hosted by DevelopMentorŪ  http://www.develop.com
NEW! ASP.NET courses you may be interested in:

2 Days of ASP.NET, 29 Sept 2003, in Redmond
http://www.develop.com/courses/2daspdotnet

Guerrilla ASP.NET, 13 Oct 2003, in Boston
http://www.develop.com/courses/gaspdotnet

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to