| Start |
|---|
| Avoiding Reading and Writing Data Simultaneously Sometimes, you want your threads to simultaneously share data. When this happens it is important to be aware of the code and lock any parts that could go wrong. A simple example of two threads counting is shown below. Here is some dangerous (incorrect) code: You'll notice, instead of counting 1,2,3,4,5... we count 1,1,2,2,3... To fix this problem, we need to lock the value of count, so that multiple different threads cannot read and write to it at the same time. With the addition of a lock and a key, we can prevent the threads from accessing the data simultaneously. |
| Creating and Starting a Second Thread If you're doing multiple long calculations, you can run them at the same time on different threads on your computer. To do this, we make a new Thread and have it point to a different method. |
| Parallel.ForEach Loop If you have a foreach loop that you want to speed up and you don't mind what order the output is in, you can convert it to a parallel foreach loop by doing the following: |
Simple Complete Threading Demo |
| Deadlocks (hold resource and wait) A deadlock is what occurs when two or more threads are waiting for eachother to complete or to release a resource in such a way that they wait forever. If thread1 holds a lock on resource A and is waiting for resource B to be released while thread2 holds resource B and is waiting for resource A to be released, they are deadlocked. Clicking button1 for the following example code will cause your application to get into aforementioned deadlocked state and hang To avoid being deadlocked this way, one can use Monitor.TryEnter(lock_object, timeout_in_milliseconds) to check if a lock is held on an object already. If Monitor.TryEnter does not succeed in acquiring a lock on lock_object before timeout_in_milliseconds, it returns false, giving the thread a chance to release other held resources and yielding, thus giving other threads a chance to complete as in this slightly modified version of the above: Note that this workaround relies on thread2 being stubborn about its locks and thread1 being willing to yield, such that thread2 always take precedence. Also note that thread1 has to redo the work it did after locking resource A, when it yields. Therefore be careful when implementing this approach with more than one yielding thread, as you'll then run the risk of entering a so-called livelock - a state which would occur if two threads kept doing the first bit of their work and then yield mutually, starting over repeatedly. |
| Creating One Thread Per Processor
The CLR will then schedule each thread to a logical processor, this theoretically could mean each thread on a different logical processor, all threads on a single logical processor or some other combination. |
Simple Complete Threading Demo using Tasks |
Explicit Task Parallism |
Implicit Task Parallelism |
| Starting a thread with parameters using System.Threading; |
| Deadlocks (two threads waiting on eachother) A deadlock is what occurs when two or more threads are waiting for eachother to complete or to release a resource in such a way that they wait forever. A typical scenario of two threads waiting on eachother to complete is when a Windows Forms GUI thread waits for a worker thread and the worker thread attempts to invoke an object managed by the GUI thread. Observe that with this code exmaple, clicking button1 will cause the program to hang.
To get around this, one can use a non-blocking way of invoking the textbox instead: However, this will cause trouble if you need to run code that is dependent on the textbox being updated first. In that case, run that as part of the invoke, but be aware that this will make it run on the GUI thread. Alternatively start af whole new thread and let that one do the waiting on the GUI thread, so that workerthread might complete. To minimize the risk of running into a deadlock of mutual waiting, always avoid circular references between threads when possible. A hierarchy of threads where lower-ranking threads only leave messages for higher-ranking threads and never waiting on them will not run into this kind of issue. However, it would still be vulnerable to deadlocks based on resource locking. RemarksA thread is a part of a program that can execute independently of other parts. It can perform tasks simultaneously with other threads. Multithreading is a feature that enables programs to perform concurrent processing so that more than one operation can be done at a time. For example, you can use threading to update a timer or counter in the background while simultaneously performing other tasks in the foreground. Multithreaded applications are more responsive to user input and are also easily scalable, because the developer can add threads as and when the workload increases. By default, a C# program has one thread - the main program thread. However, secondary threads can be created and used to execute code in parallel with the primary thread. Such threads are called worker threads. To control the operation of a thread, the CLR delegates a function to the operating system known as Thread Scheduler. A thread scheduler assures that all the threads are allocated proper execution time. It also checks that the threads that are blocked or locked do not consume much of the CPU time. The .NET Framework
Some of the delegates that are present in the Enumerations in In .NET Framework 4 and later versions, multithreaded programming is made easier and simpler through the |
Read Article
https://develop.horje.com/learn/1434/reference