i was just wondering since calling methods asynchronously in the same thread acts just like calling the method on another thread. so which is better or preferred by you programmers out there
are methods called asynchronously in the same thread better than those called in another thread

are methods called asynchronously in the same thread better than those called in another thread?
Christoffer Skjoldborg
What I posted may have been a bit confusing: when I said 'begininvoke' will create a thread, I was refering to an asyncdelegate object. When you use 'begininvoke' on a control, it is designed to marshal the call onto the the thread which owns that controls handle. It clearly states this in the documentation.
It also states the BeginInvoke is thread safe (which it should be, since it's designed for thread marshalling).
There was a reference to a previous thread (http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=973293&SiteID=1) where JerberSoft used BeginInvoke to create an (asynchronous) thread. This is different from BeginInvoke on a control: sorry for the confusion.
But I think that illustrates a point: you needc to understand the concepts, the language is irellevant (although can be confusing - obviously!) It's also one reason I believe such a high level languages should be one of the last things taught to potential programmers.
At the same time, a 'simpler' language will not help: to make things simpler, you have to put them in a sandbox. If they are in a sandbox, you can't do anything truly useful. This is the reason Java is not as popular as it could be as a programming language (in fact, overall, it's quite a simple language - even though it is full of curly braces). [I'm not going to get into any flame war about the merits of Java, so don't anybody start]. VB is an all-encompassing language that needs to statisfy all levels of programmer/engineer. The result is a program that is easy to use, but with a steep learning curve coming quickly when you try to do do 'all the cool stuff'. I think you'll find that you will be able to create a 'language' which does everything that you want it to do, but find that no-one else (a few hundred or thousand people don't count) will deem it even remotely useful.
Again, multitasking is different than multithreading - you are right: the resources need sharing in an efficient way. At a high level (VB) we use multithreading - this means we throw our code at the cpu, and the OS kernel decides how to shred it: we have no control over it. Multitasking is different: we tell the kernel what tasks we have, and the kernel decides when to run those tasks. Each task is an atomic peration. We have a good control over what ocurrs. Multitasking is a lower level operation - used, as you say, with PLCs and RTOS. VB is not designed for such environments, and has no mass appeal. In a Real Time system you need total control over certain tasks - specifically, I/O (an output write cannot be interrupted by, well, anything, theoretically).
But we are drifting away from the VB side of things: VB isn't designed for such environments - it's a desktop OS programming environment. Can it be used in stricter environments Sure, but you need a bit more care in your programming when communicating with I/O for example. Thus, the understanding of the techniques required needs to be high, and how to apply such techniques in the language (VB) offer a fairly steep learning curve.
luweewu
Thanks for the roses in your last thread. The description is just a slightly modified version of the one on our knowledgebase.
Not quite sure if I understand your new question.
Unlike the previous versions of VB, VB.NET will not allow a direct cross thread call. If you try, you will get an error message. Therefore it is necessary to use Invoke or BeginInvoke if you want to communicate between two threads. For example, the SerialPort runs on its own thread, so if you want to display data from the serial port, you need to use BeginInvoke (or Invoke).
Kohl.Mike
SJWhiteley
Are there any good descriptions of how the multithreading of VB.NET actually work Of course I have tried the help files, but they do not give the required overview.
At first I tried to write from one task to another, but of course got the "Illegal cross thread call" error message. I then found an application, which used BeginInvoke to display data received from a serial port. It works fine, but for a long time I could not figure out how it works - even though I have been working with multitask operating systems in the embedded world for almost 30 years. In almost all embedded multitask systems I have knowledge about you grip a message description from a pool when you have something to transfer, fill it out with the message and send it to a semaphore, which is just a software FIFO buffer. The receiver then receives the messages from this semaphore and returns the message description to the pool. I thought that Windows had a similar system and took it for granted that subroutines automatically was executed on the same thread as the form they were created on, but then it did not make sense that BeginInvoke used a control, which has absolutely nothing to do with the data transfer. However, suddenly I saw "the light" and realized that this is not what happens. The display routine was event driven and not automatically executed on the GUI thread. Now everything became logical, but there are still numerous question to ask about multithreading.
1) What happens if you invoke a routine once more (with new data) before it has finished the previous job
2) Because of the asynchronous nature it is logical that all event driven routines - for example the ones, which ends with "Handles xxx" - becomes its own thread, but is this the case
3) Any subroutine, which ends with "Handles xxx" is of course event driven, but can every subroutine also be event driven if you start them with an Invoke or BeginInvoke call
4) What happens if a subrotine is called or invoked more times at the same time For example, if you make a display subroutine it may be called as a traditional subroutine, but it may simultaneously be Invoked from one or more other methods/threads.
5) How do you invoke a routine or send a message to it from another thread, if it has no GUI object (control) and therefore no BeginInvoke method You are right that the BeginInvoke method do not work if you e.g. have a data processing routine between e.g. a serial port receiver and the display routine, so a more general useable method is preferred.
Programming is not difficult if you have a deep understanding of what you are doing. Then you are also able to describe it to others in easy and understandable terms, which even a beginner can understand. For example, by using an example with a postman, a postbox and envelopes for messages, I can explain multitasking in the embedded world in such a way that even a child can understand it. Can anybody do the same with .NET multithreading
sedso
What might the difference be
Not really sure what you are driving at, but regardless, the asynchronous method executes on a separate thread. So it 'acts' the same. However, you have no control over how that thread operates - it's taken from a thread pool. This may be fine for a simple operation (file I/O for example). Similarly, the background worker object offers al the benefits of asynchronous operation in a simple package. Once again, though, you don't have a lot of control over that thread.
The commonlity is that they all exist on a separate thread: with all the hazards associated with that.
The difference is in the method of invocation of that thread, and what control you have. No method is 'better' than the other.
Personally, I almost always create the thread manually and deliberately, and keep the thread count to a minimum. I'll use the background worker as a quick and dirty, but have never used the begininvoke to create an asynchronous operation.
Bob Hodgman
You didn't state that you are refering to windows controls only. This is only by default. You can access windows controls directly from another thread, without using invoke, by setting checkforillegalcrossthreadcalls to false (you probably wouldn't want to, though).
No, no, no, this is an incorrect statement.
In a situation when you need to marshal a call back onto a thread with controls you want to access, you do not use beginInvoke, you use invoke only. However, if you are NOT accessing any controls, then you do not need to invoke anything (but remember it is on a separate thread).
Even so, it is not absolutely necessary to use Invoke to display data from another thread (a serial port as mentioned). You can use other thread locking methods to transfer data to and from different threads (e.g. Synclock: one of the easiest and simplest methods).
Generally, you would want to separate your data collection from your data presentation with (even a trivial) data analysis layer. By performing an Invoke on your presentation layer directly from the data collection layer you are forcing the presentation layer to effectively operate 'synchronously' with the data collection layer. This is a poor architecture, and not scalable.
Candela
thanks for clarifying it to me. so in other words, its upto the programmer's decision in what we would use and what he is familiar with isn't it ;-)
KevinBurton
“I do not think that the difference between multitasking and multithreading is so big. The basic goal of the two systems is exactly the same - to be able to run more programs or program parts virtually simultaneously. This may of course be done in many ways. In a typical multitask system in the embedded world, the programmer chooses the switch points, but there is a timer, which prevents an infinite runtime, if the programmer forgets to release the CPU (it do not only run one task at a time). A multithreading system is - as far as I know - typically only run by the timer plus perhaps a little more intelligence. A multitasking or multithreading system - call it what you like - may also be entirely event driven and based on an evaluation queue. Such a system is extremely simple and efficient and do not require any system calls at all.”
Hi Carsten,
Let me begin by saying that I’m not writing this as any authority who is here to “prove” you wrong. I do have a couple of observations.
Windows is the third Cutler operating system I’ve worked on over the past thirty years. I’m an operating systems engineer and I’m going to have a different perspective than you will and I have lived it eighteen hours a and sometimes more for fourteen years.
It’s not fun to say, but VB and the entire CLR is but the tip of the ice berg. VB is designed so that the real operations under the hood are made transparent and only surface on occasion like the BeginInvoke conservation. Yes, there are different threads but the concerns of what goes on at the driver level are quite different. Intel machines are becoming quite complex BUT simply because of the historicity of PC the hardware lacks some of the really finer points of Cutler’s second operating system VMS. Yes, we had to worry about multiple threads, some of the things I’ve been thinking about lately is the fact that the way a lot of it was handled was by fundamental hardware design where hardware was designed for an operating system and set of products. The intel architecture was around before DOS and DOS adapted to the architecture. Neither has ever been designed for each other because unfortunately one company’s interest is silicon and the other company’s interest is being able to run on that silicon and one follows the other. Actually in my readings, since intel designs the hardware features quite independently Microsoft has to run on what is manufactured and in this manner Intel leads and there is never parity or a true integration of hardware and software. It may be obscure but I’m going somewhere with is. An example of what I am saying is that Microsoft could write all the 64 bit software that it wanted to but if there were no silicon that would address more than 32 bits, the 64 bit software would remain pseudo-code would it not
I think some careful distinctions need to be maintained. Multi-tasking is not the same as asynchronous execution although asynchronous execution facilitates multi-tasking. Unix multi-tasked for years and had no asynchronous capabilities, something that seemed really alien to us at Digital, so indeed they are not the same. VMS was asynchronous and multithreaded to begin with in ways that DOS was not and still are. It had to be added and it had a be added on limited hardware which in my eyes still has significant architectural limitations although it performs well.
True asynchronous I/O is of course hardware dependent and requires something more than just a processor. One example is IE. Eventually, regardless of what occurs, IE depends on a hardware device for I/O completion which is an ethernet card or a modem waiting on server perhaps on the othe side of the world.
“A multithreading system is - as far as I know - typically only run by the timer plus perhaps a little more intelligence. A multitasking or multithreading system - call it what you like - may also be entirely event driven and based on an evaluation queue. Such a system is extremely simple and efficient and do not require any system calls at all.”
I suggest that we not call it what we like because to make sense out of this conversation I believe we need to be mindful of engineering distinctions. The first sentence really doesn’t sense to me. You asked a question earlier about events and “the same thread.” The behavior of the system is that an asynchronous timer event on a form is the same thread as the form which is it’s owner. In fact, there’s no way to identity the owner any thread unless there are datastructures in place to that to do that.
A little more intelligence Carsten are you forgetting that there is an operating system underneath that is running on some hardware platform and it has taken quite a lot of intelligence as a facility to deliver that timer thread. Again, pplease remember that unix didn't even have that for may years. Every once in a while it would pole to find out what time it was.
Knowing what I know about VMS, we really can’t have this discussion in the absence of a pretty clear understand of how the operating system delivers an asynchronous event such as a timer firing to a process. I believe if you looks under Windows hood you’ll find Unix-Like structure where there are process wait queues ready to receive asynchronous messages and to process them as call backs. In VMS, there were IPL (Interrupt Priority level) levels for doing certain tasks. ASTs asynchronous traps such as timer expiration and I/O completion were delivered to a process at IPL 2. Some IPLs were hardware IPL and some were software. But there was also a hardware SIR (software interrupt register). All of this makes it really nice when one company designs both but the hardware and the software so that they are compatible and this was what made VMS the work of art that it was.
I am suggesting that one can do multithreading if one has something to wait on such as hardware or a user manipulandum expressed in hardware. A thread that doesn’t do I/O starts and runs to end of execution as per the developers specifications. Threads can be entirely software exections. By definition, asynchronous operation comes from a source external to a process… even when it’s a timer because hardware is driving it. When a timer thread is delivered it’s being delivered because request was made against a hardware clock or where a user has pressed a mouse. These events are asynchronous to the execution of software. That’s what asynchronous means.
There are some examples of asynchronicity available to the Windows Application programmer, but not many. Why Because windows has been designed to hide that just as programming flexibility has been limited in VB and the other CLR languages. Apparently the mainstay thinking has been to protect applications programmers from the demands real multithreading places on programmers and that’s one thing I resent about VB.Net. returning to what I said earlier, part of this is because that the hardware wasn’t made for the software as we did at Digital. Cutler was part of the team that wrote the instruction set and designed the hardware architecture of VAXes for the VMS operating system. Cutler at Microsoft doesn’t have that luxury and hence, under the hood, Windows in this respect looks more like Unix as an operating system that was made for any hardware platform which is why Unix couldn’t do anything asynchronously for years. This independence in hardware and software design can’t help but to put Microsoft in a position where they are constantly “adapting to” a hardware environment and historically that has been the case.
How does all of this manifest itself It manifests itself in terms of a development community that becomes foggy about what goes on under the hood and looses the distinction and becomes loose about basic fundamental distinction. It also means that users are likely to remain foggy about the finer points of asynch and thread synchronization. These are difficult distinctions to learn unless you began and worked for years with hardware and software that were made to do just this. We didn’t have any choice about whether to learn asychn or not. Cutler’s first operating system was called RSX-11M which was a real time multitasking operating operating system. Asynch was a matter of course in ways that Unix people could not conceptualize. I see we’re sort of getting back to that now.
"So any subroutine - event driven (Handles xxx) or not event driven - always runs on the same thread as the program or method from which it is called, activated or invoked. Is this true "
I think you have to remember that the extent to which this is true will be a direct artifact of the operating system itself. It's not a fact of nature and in this respect is both arbitrary and designed. By arbiratry, I mean it is so because it's been decided that this is so.
Paulson Abraham
Hi ReneeC
Nice to hear from you. I can see that you really "burn" for operating systems and that this has become a great part of your life.
As an electronic engineer I agree with you that many of the problems today are coursed by the fact that hardware designers and programmers do not talk as much together as they should. Just look at the [IT Visions][Programming] pages of our homepage - I do not dare to give the direct link anymore ;-) but you should read it. It may interest you.
Hardware designers and software nerds live in two different worlds. The hardware designer knows that hardware costs, but many nerds have the opinion that if a program runs too slow, it is just because the hardware is not fast enough, and if you run out of memory, it is just because there is not enough memory in the computer. In the worlds of the nerds, errors are accepted and have no consequence, but in the hardware world, errors may cost you an enormous amount of money or even your life! I have seen nerds with Christmas lights in their eyes talk about managed code and automatic garbage collection, but I have newer seen anyone of these talk about a DO-178 (safety) approved core, which one time for all could save us for all problems with virus and hackers. If you have a car with ESP (Electronic Stability Program) and runs it at high speed you actually put your life in the hands of the ones, who have designed this safety system, because if it suddenly locks the wheels in the same side, your car will get out of control and you may be killed. Would you trust your life in the hands of Windows
In the early days, the two groups worked much better together. For approximately 25 years ago I worked on a project, which run on a RC3000 minicomputer from the Danish company Regnecentralen (gone long time ago). This computer was designed for communication tasks and had 128 register pairs, so you did not have to save anything during interrupt or task switching.
However, although I do agree with you, I will not blame it all on hardware. Since 1979 I have worked with event driven (fully asynchronous) PLC systems. In the beginning this system run on a 2MHz Intel 8080 microcomputer with 6K RAM and 8K EEPROM, but nevertheless we could control approximately 80 conveyors and/or valves with such a system and due to the asynchronous event driven architecture the response time was usually less than 100 mS. Today, there are at least three companies, which offer DO-178 approved operating systems for almost all microprocessors, which have a memory manager, so good operating systems do not depent entirely on hardware.
For the moment, I am working on an asynchronous network with approximately 2000 gates for our new fieldbus system Max-i so I know a little about asynchronous design and the problems with meta stability, glitches and getting things synchronized. I can assure you that if programmers have problems with asynchronous calls, the problems for hardware designers is many, many times bigger! For example, it is easy to make a FIFO (First In First Out) in software, but in hardware it is one of the most tricky jobs because of the meta stability. Actually, the 16 byte FIFO in the first two versions of the 16550 UART - the one in the PC - did not work. The reason why almost all computers today are clock synchronous is that - until recently - even the best designers have not been able to make an asynchronous design, which works, although there are many benefits to gain with such a design.
To me, the question about multitasking and multithreading is just a question about names. The basic problem is the same. Most computers have only one core, one memory, one screen and so on, so it is just a matter of sharing the resources in the most efficient way. As I have said before, this may of course be done in many ways. Some of these may be called multithreading and some may be called multitasking, but I have newer seen a short and precise definition of what is multitasking and what is multithreading. Many early operating systems used interrupts (hardware and software) to perform the switching, and today somebody like Torsten Sellergren from Tritech System Technology talks about a simple synchronous scheduler for RTOS (Real Time Operating Systems) as being more efficient than the usual asynchronous one. Our own suggestion for a new VB like programming language B# is yet another way of dealing with these problems based on our long experience with event driven PLC systems. Like Torsten Sellergren, we try to simplify thing for getting a higher efficiency in the same way as the efficiency of microprocessors has been increased by reducing the instruction set (RISC contra CISC).
Jim Thompson
Carsten,
Yes I do burn for operating systems. They can be a beautiful work of art and they can be a mess. I guess you can tell, I really do miss VMS.
"The hardware designer knows that hardware costs, but many nerds have the opinion that if a program runs too slow, it is just because the hardware is not fast enough, and if you run out of memory, it is just because there is not enough memory in the computer. In the worlds of the nerds, errors are accepted and have no consequence, but in the hardware world, errors may cost you an enormous amount of money or even your life! "
Please see my signature!
Your example of the controllers in cars were rather interesting. So in the future recalls will be in the form of taking your car in for a firmware update. J“good operating systems do not depent entirely on hardware.”
I think there needs to be a marriage. Looking at the code will reveal the degree of health of the marriage because indeed there is an attempted relationship. For Vax/VMS it was close to perfect. It’s funny, many times I’ve heard it said that the intel instruction set is “Vax-like” but when I do intel assembler, I don’t see. It’s a mess, bogged down by the history of the X86. There has never been a clean break from the 8086. That was another nice thing about VMS. I mentioned Cutler’s first operating system RSX which ran on a 16 bit . His second was built on a new hardware architecture and he was a part of the architecture group that specified the instruction set. The hardware was designed to run VMS and VMS was designed to run of the hardware. The instruction set was created a calling convention for subroutines which meant that the same image “assembly” could be comprised of modules written in Bliss, Fortan, C, Cobol or even compiled basic.
“To me, the question about multitasking and multithreading is just a question about names. The basic problem is the same. Most computers have only one core, one memory, one screen and so on, so it is just a matter of sharing the resources in the most efficient way. As I have said before, this may of course be done in many ways. Some of these may be called multithreading and some may be called multitasking, but I have newer seen a short and precise definition of what is multitasking and what is multithreading.”
You won’t see such a definition because these things are defined on a per OS basis. The definition is architecture dependent. They are both managed by the Kernel as SJ says, but they are managed at very different levels. Is do see things a little differently than SJ. Everything is a request to the kernel which has its eye on optimizing overall system throughput. From an application’s perspective a thread is in service to a very specific application and has a specific task that the application knows about. The kernel makes context switches between processes based on it’s assessment of the overall workload.
" I think that one of the biggest mistakes with "everyman" languages like VB is to say that this is on a "Don't need to know basis".
That would be every persons.... Did you know a woman authored the first BitBlt making GUIs possible
Criminet
You are absolutely right :)
It's qute easy to get the actual code written to perform a function (copy and paste, and voila: it works). Quite another to actually understand it, and the repercussions.
There's more to programming than bashing out code - lots of decisions to make. We start out as coders, gain understanding to become programmers, and some of us eventually become actual software engineers - and actually become what that diploma says we are :)
Ed de los Reyes
Thanks a lot for your reply.
I am fully aware of the problems with non thread safe calls, but it actually gets very interesting because if it is true what you tell me then BeginInvoke is not a thread safe method!!!
Let us take the old example with the serial port receiver, which starts a display routine on the same thread as TextBox1 by means of TextBox1.BeginInvoke.... The first time there are data from the serial port, the display routine is started on the same thread as TextBox1, so that it can write in a thread safe way. However, BeginInvoke returns immediately once the display routine is started, so if the serial port receiver is faster than the display routine it may invoke the display routine once more before the display routine has finished its job. If the next BeginInvoke call activates the display routine on a new thread, as you write, then it can no longer write in a thread safe way (two different threads), so either is BeginInvoke not thread safe, or there is something wrong with the explanation! This situation is actually the reason for my question 1 (and 4).
So any subroutine - event driven (Handles xxx) or not event driven - always runs on the same thread as the program or method from which it is called, activated or invoked. Is this true If this is the case, it is a violation of this rule if more calls of BeginInvoke create new threads. It is more logical that each thread has an evaluation queue for the methods, which want to run on that thread, so that more subsequent calls of BeginInvoke just puts the methods in this queue.
I do not think that the difference between multitasking and multithreading is so big. The basic goal of the two systems is exactly the same - to be able to run more programs or program parts virtually simultaneously. This may of course be done in many ways. In a typical multitask system in the embedded world, the programmer chooses the switch points, but there is a timer, which prevents an infinite runtime, if the programmer forgets to release the CPU (it do not only run one task at a time). A multithreading system is - as far as I know - typically only run by the timer plus perhaps a little more intelligence. A multitasking or multithreading system - call it what you like - may also be entirely event driven and based on an evaluation queue. Such a system is extremely simple and efficient and do not require any system calls at all.
Hendrikbez
Multithreading in VB works exactly the same as in any other language. This is why it's a good idea to learn something like C (with a touch of assembler) and then move on to the higher level languages. You don't need to know exactly how a multithreaded operating system does it's job, but know the repercussions of programming in a mutithreaded environment.
Specifically, you cannot use the line:
i += 1
from multiple threads and expect the global variable 'i' to be correct. This i a fundamental concept (that VB statements are not atomic) that needs to be understood. Unless the documentation says otherwise any command or operation is not 'thread safe'. The above command is not 'thread safe'.
Likewise, and specifically, controls are not thread safe. Consider: what would happen if you changed the text of a text box in one thread, and changed the font in another thread Or even resized a text box while the text was changed in another thread
You can 'invoke' a routine any number of times as you like. There's nothing stopping you. if you use the 'begininvoke' It'll create a new thread and do its thing. If you access global data outside that routine, yu'll probably get incorrect results, though.
Any subroutine which ends with 'handles' does not necessarily get it's own thread: it depends on the thread which calls it. The 'handles' is a nice connector word which allows you to tie an event to a subroutine (AddHandler can do the same thing). If the caller of that subroutine is running on another thread, then that routine will run on that thread. All pretty simple.
There are built in checks for visual controls, though: because people get into trouble trying to update user controls from another thread than the one they were created on (e.g. changing text and font simultaneously). So, what you need to do is check the thread the control is running on: if it's the same thread then we can directly update the control knowing that no other command/subroutine on that thread is operating -we can't start to update the font, then update the text, then complete updating the font: can't happen on a single thread.
If the routine is called from another thread, you can use the InvokeRequired command: all this does is check the thred identity of the thread that owns the handle to the control: if it matches the current thread, all is good, if it doesn't, it'll return true - the threads are different. This execution of the subroutine needs to be marshalled into the thread which owns the control. How it does it is irellevant, you just need to know how to get the 'function call' marshalled to that thread, so you don't get any multithreading issues. There is an overhead to performing this marshaling, however.
You can marshal function calls between two threads which don't have controls: simply check the threadIds and compare them (actually, perhaps not so simple - remember that a call to get the threadId may not be thread safe).
Multithreading is not the same as multitasking: they are very, very different. Multitasking as applied to embedded systems means that the CPU will only perform a single task at once; and typically your multitasking kernel is written in such a way that all tasks are atomic (e.g. a PLC updating the I/O). The windows OS is a complex kernel which best judges when to break up program execution. Which means:
if one thread sets a value (i=1).
Then the same thread increases it by one (i+=1).
Another thread also increases it by one (i+=1).
What is the value of i It can either be 2 or 3...depending on how the OS broke up the threads.
Multithreading itself is quite a straightforward concept. Using multithreading is another job entirely. Great care is needed to ensure data integrity.
hye_heena
Thanks for your explanation. It is a very good definition of the difference between multitasking and multithreading, but still not precise.
In a multithreading system, the OS has indeed knowledge about the various threads in the same way as a multitask system has knowledge about the various tasks, and you can create new threads as you can create new tasks in a multitask system. Of course, if you make a program, which do not use I/O, you can forget about threads, but you can do the same in a multitask system like AmigaDOS in the Commodore Amiga (I am from those days).
Of course BeginInvoke is thread safe - it is the whole idea, but this means that each thread must have an evaluation queue where all methods are stored until it is their turn to run or else BeginInvoke would not be thread safe as I proved before. However, this is exactly the same thing, which happens in a multitask system, where tasks waiting to run are also put into a queue. Besides, the size of a task is approximately the same as the size of the methods/subroutines, which are put into the thread queue by means of Invoke, BeginInvoke and events (Handles xxx), so if you regard a task and an event driven subroutine as being the same, multitasking and multithreading is also very much the same. You may say that:
Is this correct, and is it correct that each thread has a queue for methods waiting to run
As I have said before, neither multitasking nor multithreading is difficult to understand and handle if you know exactly what goes on below the hood. I think that one of the biggest mistakes with "everyman" languages like VB is to say that this is on a "Don't need to know basis". This term only belongs to spy movies :-)
Nagaraj K
ReneeC
Sorry, I didn't mean to offend you. With everyman I just meant everyone. I know that you are a woman, and I have nothing against female programmers. My wife is a programmer too (embedded multitask systems), and one of the first multitask operating systems in Denmark (approximately 1977) was also written by a woman - Bodil Skroeder as far as I remember.
I do not regard you as a software nerd. Being from the old days you have learned how to make things work even with very limited resources. In fact, I think that we have quite a lot in common, but we are a dying race. The true teaching today is programming in C# with absolutely no thought on efficiency.
By the way, what do you call a female postman ;-)