When we compile and run a project in C#, the program is executed in its own process. A process has its own address space, memory assigned to it. The executable code is in the address space. A modern computer executes several processes at a time, switching between them every so often.
The idea of a thread is that one process could be split into several parts, each being executed "at the same time". They all live in the same address space and they are executing the same excutable code, though not the same part of it.
For example, a web browser may be displaying data (and responding to the user moving the mouse, etc.) while it is "simultaneously" downloading more data. This would require at least two threads.
A process always starts out as one thread, executing Main(). It can create more threads which then run independently, taking turns during tiny time slices.
Thread Class
This is in the System.Threading namespace.
Constructors (some of them)
This creates a thread. ThreadStart is a delegate whose value is a method which the thread will start executing. The method will have no arguments and return void. That is, we have
ThreadStart S = new ThreadStart(Methodname); Thread T = new Thread(S); T.Start();
This is similar but the method we are executing may have one argument (of type Object). The argument is supplied when we use the Start() method. That is, we have:
ParameterizedThreadStart S = new ParameterizedThreadStart(MethodName); Thread T = new Thread(S); T.Start(X);
where X is an argument of type Object to be passed to MethodName.
This is similar but needs only the method name. C# will figure out which constructor is needed. As this is easier, it is often used.
Properties (some of them)
This returns the currently executing thread.
public bool IsBackground { get; set; }
This indicates whether this thread is currently running in the foreground (false) or in the foreground (true). A process ends when all foreground threads have ended; there could still be background threads and they will be stopped.
A thread may optionally have a name. The default value is null. This is a write-once property; we cannot give a thread a name and change it later.
A thread has an assigned priority. Threads with higher priorities are (theoretically) given precedence and should execute before those with lower priorities. Here ThreadPriority is an enumeration with values AboveNormal, BelowNormal, Highest, Lowest and Normal. The default is Normal. (The operating system is not guaranteed to pay attention to this.)
Methods (some of them)
This causes the thread to begin execution.
This raises a ThreadAbortException. It will end the thread and usually the process as well.
These suspend the calling thread (putting it to sleep) for a period of time indicated by the argument. Here TimeSpan is a struct representing an amount of time which can be indicated by its properties such as Milliseconds.
This is used by a thread to cause the calling thread to be blocked (pause execution) until the thread whose join method is called has terminated. (Wait until the other thread is done. For instance, we may have threads T1 and T2. In the code executed for T1, we might have
(code) T2.Join(); (code)
A thread should never call join() on itself, which would cause an indefinite delay.