amdrit said:
Jon help me learn something new here. I am not understanding your
alternative or perhaps your reservations with sleeping a thread.
say I have a worker process processing in a loop
do
{
// work code here
//Now let someone else talk to the processor
Thread.sleep(0)
} loop while (notdone == true)
How does setting the thread priority ensure that the work gets completed
and allows other processes to process? Isn't that one reason sleep was
made for? I come from VB where we were told to DoEvents everywhere, where
VB wasn't "threadable". Now that we are in a "threaded" environment we
are told not to thread and asked to refrain from sharing with the other
processes, what am I missing?
In VB 6, the processing in your app almost always occurs on the same OS
thread as the user interface. When you see a program report "Not
Responding", what has happened is that the user interface OS thread has
gotten busy and is not checking the message queue. The DoEvents() call is
how a Windows GUI application can handle new messages and keep its
processing on the UI thread.
Note that console apps very rarely show "Not Responding" because the
Win32/64 console subsystem puts a layer between the application's input
queue and the underlying windows message queue.
In dotNet 2.0 - the basic Windows Form application has the same performance
issues as a VB 6 application. A dotNet Console application (and VB 6 apps
that use the Windows Console API calls) become "native" console
applications. dotNet also provides direct access to the operating system
threads through the the System.Threading.Thread class and the
System.Component.BackgroundWorker class. In addition, the dotNET framework
creates a pool of threads designed for short lived tasks such as IO
completion and exposes them through the ThreadPool - that's a completely
different discussion, however.
The question becomes "when should I use threads?" The answer depends on two
primary conditions. First, do you have long, computation or non-UI io bound
tasks that don't require interaction with the user. In this context, long
is "human real-time", or longer than about one and a half to two seconds.
Next, are these long tasks relatively independent of each other. If not,
they may not be good candidates for multi-threading as inter-thread
synchronization and communications can become debugging nightmares and
performance bottlenecks. Assuming you decide to use System.Threading, you
need to remember that updating your UI from the thread requires some
synchronization because the underlying Windows API doesn't like cross thread
updates to the UI thread. Anytime a Window is updated, messages are
generated and the source data addresses for the messages must be guaranteed
to exist (and not change) until after the UI message is processed. For this
situation, use the System.Component.BackgroundWorker class as it provides a
defined interface for updating the UI. In either case, if your thread is
CPU intensive, take a look at System.Thread.Thread.Priority property, which
you can use on any thread to control the thread's processing priority. For
CPU intensive threads, you might want to have the following line near the
beginning of the thread "System.Threading.Thread.CurrentThread.Priority =
ThreadPriority.BelowNormal" to tell the OS that this thread is not to
interfere with other applications, or even the UI thread of your
application. If your thread does a lot of disk or network IO, don't worry
about setting the thread priority as anytime a thread is in a wait state for
IO operations, it's taken out of the list of processing threads until the IO
completes.
In your application, I suspect that some external event triggers the need
for the background processing. If you can capture that event in a class and
then pass that class to a procedure, take a look at the ThreadPool as it
queues task requests. This way you could actually eliminate the do forever
loop in your sample.
Mike.