Sunday, 15 September 2013

Introduction of  Parallelism Threading

ith this post I want to start a series devoted to the new parallel programming features in .NET Framework 4 and introduce you the Task Parallel Library (TPL).
Update. The list of posts in this series:
I have to admit that I’m not an expert in multithreading or parallel computing. However, people often ask me about easy introductions and beginner’s samples for new features. And I have an enormous advantage over most newbies in this area – I can ask people who developed this library about what I’m doing wrong and what to do next. By the way, if you want to ask someone about what to do next with your parallel program, I'd recommend you to go to this forum - Parallel Extensions to the .NET Framework Forum.
I have a simple goal this time. I want to parallelize a long-running console application and add a responsive WPF UI. By the way, I’m not going to concentrate too much on measuring performance. I’ll try to show the most common caveats, but in most cases just seeing that the application runs faster is good enough for me.
Now, let the journey begin. Here’s my small program that I want to parallelize. The SumRootN method returns the sum of the nth root of all integers from one to 10 million, where n is a parameter. In the Main method, I call this method for roots from 2 through 19. I’m using the Stopwatch class to check how many milliseconds the program takes to run.
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;
using System;

class Program
{

    static void Main(string[] args)
    {
        var watch = Stopwatch.StartNew();
        for (int i = 2; i < 20; i++)
        {
            var result = SumRootN(i);
            Console.WriteLine("root {0} : {1} ", i, result);
        }
        Console.WriteLine(watch.ElapsedMilliseconds);
        Console.ReadLine();
    }

    public static double SumRootN(int root)
    {
        double result = 0;
        for (int i = 1; i < 10000000; i++)
        {
            result += Math.Exp(Math.Log(i) / root);
        }
        return result;
    }
}
On my 3-GHz dual-core 64-bit computer with 4 GB of RAM the program takes about 18 seconds to run.
Since I’m using a for loop, the Parallel.For method is the easiest way to add parallelism. All I need to do is replace
for (int i = 2; i < 20; i++)
{
    var result = SumRootN(i);
    Console.WriteLine("root {0} : {1} ", i, result);
}
with the following parallel code:
Parallel.For(2, 20, (i) =>
{
    var result = SumRootN(i);
    Console.WriteLine("root {0} : {1} ", i, result);
});
Notice how little the code changed. I supplied start and end indices (same as I did in the simple loop) and a delegate in the form of a lambda expression. I didn’t have to change anything else, and now my little program takes about 9 seconds.
When you use the Parallel.For method, the .NET Framework automatically manages the threads that service the loop, so you don’t need to do this yourself. But remember that running code in parallel on two processors does not guarantee that the code will run exactly twice as fast. Nothing comes for free; although you don’t need to manage threads yourself, the .NET Framework still uses them behind the scenes. And of course this leads to some overhead. In fact, if your operation is simple and fast and you run a lot of short parallel cycles, you may get much less benefit from parallelization than you might expect.
Another thing you probably noticed when you run the code is that now you don’t see the results in the proper order: Instead of seeing increasing roots, you see quite a different picture. But let’s pretend that we just need results, without any specific order. In this blog post, I’m going to leave this problem unresolved.
Now it’s time to take things one step further. I don’t want to write a console application; I want some UI. So I’m switching to Windows Presentation Foundation (WPF). I have created a small window that has only one Start button, one text block to display results, and one label to show elapsed time.
The event handler for the sequential execution looks pretty simple:
private void start_Click(object sender, RoutedEventArgs e)
{
    textBlock1.Text = "";
    label1.Content = "Milliseconds: ";

    var watch = Stopwatch.StartNew();
    for (int i = 2; i < 20; i++)
    {
        var result = SumRootN(i);
        textBlock1.Text += "root " + i.ToString() + " " +
                           result.ToString() + Environment.NewLine;

    }
    var time = watch.ElapsedMilliseconds;
    label1.Content += time.ToString();
}

Compile and run the application to make sure that everything works fine. As you might notice, UI is frozen and the text block does not update until all of the computations are done. This is a good demonstration of why WPF recommends never executing long-running operations in the UI thread.
Let’s change the for loop to the parallel one:
Parallel.For(2, 20, (i) =>
{
    var result = SumRootN(i);
    textBlock1.Text += "root " + i.ToString() + " " +
                        result.ToString() + Environment.NewLine;

});
Click the button…and…get an InvalidOperationException that says “The calling thread cannot access this object because a different thread owns it.”
What happened? Well, as I mentioned earlier, the Task Parallel Library still uses threads. When you call the Parallel.For method, the .NET Framework starts new threads automatically. I didn’t have problems with the console application because the Console class is thread safe. But in WPF, UI components can be safely accessed only by a dedicated UI thread. Since Parallel.For uses worker threads besides the UI thread, it’s unsafe to manipulate the text block directly in the parallel loop body. If you use, let’s say, Windows Forms, you might have different problems, but problems nonetheless (another exception or even an application crash).
Luckily, WPF provides an API that solves this problem. Most controls have a special Dispatcher object that enables other threads to interact with the UI thread by sending asynchronous messages to it. So our parallel loop should actually look like this:
Parallel.For(2, 20, (i) =>
{
    var result = SumRootN(i);
    this.Dispatcher.BeginInvoke(new Action(() =>
        textBlock1.Text += "root " + i.ToString() + " " +
                           result.ToString() + Environment.NewLine)
         , null);
});
In the above code, I’m using the Dispatcher to send a delegate to the UI thread. The delegate will be executed when the UI thread is idle. If UI is busy doing something else, the delegate will be put into a queue. But remember that this type of interaction with the UI thread may slow down your application.
Now I have our parallel WPF application running on my computer almost twice fast. But what about this freezing UI? Don’t all modern applications have responsive UI? And if Parallel.For starts new threads, why is the UI thread still blocked?
The reason is that Parallel.For tries to exactly imitate the behavior of the normal for loop, so it blocks the further code execution until it finishes all its work.
Let’s take a short pause here. If you already have an application that works and satisfies all your requirements, and you want to simply speed it up by using parallel processing, it might be enough just to replace some of the loops with Parallel.For or Parallel.ForEach. But in many cases you need more advanced tools.
To make the UI responsive, I am going to use tasks, which is a new concept introduced by the Task Parallel Library. A task represents an asynchronous operation that is often run on a separate thread. The .NET Framework optimizes load balancing and also provides a nice API for managing tasks and making asynchronous calls between them. To start an asynchronous operation, I’ll use the Task.Factory.StartNew method.
So I’ll delete the Parallel.For and replace it with the following code, once again trying to change as little as possible.
for (int i = 2; i < 20; i++)
{
    var t = Task.Factory.StartNew(() =>
    {
        var result = SumRootN(i);
        this.Dispatcher.BeginInvoke(new Action(() =>
            textBlock1.Text += "root " + i.ToString() + " " +
               result.ToString() + Environment.NewLine)
            ,null);

    });
}

Compile, run… Well, UI is responsive. I can move and resize the window while the program calculates the results. But I have two problems now:
1. My program tells me that it took 0 milliseconds to execute.
2. The program calculates the method only for root 20 and shows me a list of identical results.
Let’s start with the last one. C# experts can shout it out: closure! Yes, i is used in a loop, so when a thread starts working, i’s value has already changed. Since i is equal to 20 when the loop is exited, this is the value that is always passed to newly created tasks.
Problems with closure like this one are common when you deal with lots of delegates in the form of lambda expressions (which is almost inevitable with asynchronous programming), so watch out for it. The solution is really easy. Just copy the value of the loop variable into a variable declared within the loop. Then use this local variable instead of the loop variable.
for (int i = 2; i < 20; i++)
{
    int j = i;
    var t = Task.Factory.StartNew(() =>
    {
        var result = SumRootN(j);
        this.Dispatcher.BeginInvoke(new Action(() =>
             textBlock1.Text += "root " + j.ToString() + " " +
                                 result.ToString() + Environment.NewLine)
             , null);
    });
}
Now let’s move to the second problem: The execution time isn’t measured. I perform the tasks asynchronously, so nothing blocks the code execution. The program starts the tasks and goes to the next line, which is reading time and displaying it. And it doesn’t take that long, so I get 0 on my timer.
Sometimes it’s OK to move on without waiting for the threads to finish their jobs. But sometimes you need to get a signal that the work is done, because it affects your workflow. A timer is a good example of the second scenario.
To get my time measurement, I have to wrap code that reads the timer value into yet another method from the Task Parallel Library: TaskFactory.ContinueWhenAll. It does exactly what I need: It waits for all the threads in an array to finish and then executes the delegate. This method works on arrays only, so I need to store all the tasks somewhere to be able to wait for them all to finish.
Here’s what my final code looks like:
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    public static double SumRootN(int root)
    {
        double result = 0;
        for (int i = 1; i < 10000000; i++)
        {
            result += Math.Exp(Math.Log(i) / root);
        }
        return result;
    }

    private void start_Click(object sender, RoutedEventArgs e)
    {
        textBlock1.Text = "";
        label1.Content = "Milliseconds: ";

        var watch = Stopwatch.StartNew();
        List<Task> tasks = new List<Task>();
        for (int i = 2; i < 20; i++)
        {
            int j = i;
            var t = Task.Factory.StartNew(() =>
            {
                var result = SumRootN(j);
                this.Dispatcher.BeginInvoke(new Action(() =>
                     textBlock1.Text += "root " + j.ToString() + " " +
                                         result.ToString() +
                                         Environment.NewLine)
                , null);
            });
            tasks.Add(t);
        }

        Task.Factory.ContinueWhenAll(tasks.ToArray(),
              result =>
              {
                  var time = watch.ElapsedMilliseconds;
                  this.Dispatcher.BeginInvoke(new Action(() =>
                      label1.Content += time.ToString()));
              });

    }
}
Finally, everything works as expected: I have a list of results, the UI does not freeze, and the elapsed time displays correctly. The code definitely looks quite different from what I started with, but surprisingly it’s not that long, and I was able to reuse most of it (thanks to lambda expression syntax).


Multi-core machines are dominant these days and one could easily find machines with multicore by default. Do we have to change the way we write programs? Wouldn’t running my program on a multi-core machine automatically improve performance? After all aren’t there more threads?
The answer is no! Running a program on a multi-core machine has nearly zero performance enhancements. With the exception of IO operations, your program will still use one thread of a single core at a time. Thread switching occurs – which by the way incurs overheads but at all times, only one thread will be active
What does multithreading have to do with multi-cores? Can’t we write multi-threaded codes if we have a single core? Yes, we can. But again, as long as we have a single core, only one thread at a time will work since all threads belong to that same single core… logical enough. When your multi-threaded program runs on a multi-core machine, threads belonging to different cores will be able to run together and hence your program will take advantage of the hardware power.

Multithreading vs. Parallelism

It is useful to point out the difference between traditional multithreading and parallel programming. In the past, most computers had a single CPU and multithreading was used to take advantage of idle time, such as when a program blocks for user input. Using this approach, one thread can be executed while another is waiting. On a single-CPU system, multithreading is used to allow two or more tasks to share the CPU. Although this type of multithreading will remain useful, it was not designed for situations in which two or more CPUs are available.
When multiple CPUs are present, a second type of multithreading capability is needed because it is possible to execute portions of a program simultaneously, with each part executing on its own CPU. This can be used to significantly speed up the execution of some types of operations, such as sorting, transforming, or searching a large array.

Challenges in Development

Microsoft .NET 4 comes with a host of new features that makes enterprise application development more productive and manageable. .NET has had support for parallel programming since version 1.0, now referred to as classic threading, but it was hard to use effectively and made you think too much about managing multiple threads of the parallel aspects of your program, which detracts from focusing on what needs to be done.
While developing and running with custom applications using Microsoft .NET platform, there are many challenges observed across enterprises, however it is not exhaustive. One of them would be
  • Faster and efficient processing of complex algorithms and large data sets
  • Currently Hardware manufacturers are not able to increase the speed of individual CPUs; instead they are increasing the cores to provide high speed. Due to this trend, multi core processors are becoming the order of the day. There is hardly an enterprise where applications are not running on multi core servers, but still there is no direct correlation of improvement in performance. This enables parallel activities and avoids dead locks is challenging tasks for developers.
  • Within the Microsoft Technology Center, a performance benchmarking of the same program on single core and then a multi core system was carried out.  It was found that the performance of the application did not increase significantly just by adding cores unless the underlying program constructs were adapted to multi core architecture. They are in the process publishing this research and an improvement from using parallel programming APIs is in the pipeline.

Addressing Challenges

  • .NET Framework 4 introduces a parallel library with new a programming model that considerably simplifies development and debugging of applications and can take advantage of the modern multi core hardware. The parallel library takes care of various complexities related to multi-core programming like synchronization issues, locking, task division, etc. and can automatically distribute work to multiple cores depending on their availability under the hood leaving the developers to focus on the business processes.
  • Importantly, programs written or targeted for multi-cores can also run on single core machines without any syntax or configuration changes. However programs that are not written using parallel API needs to be changed/adapted to use parallel API if it is to get performance benefit from multi core architecture, though the change in program is a very small. Enterprises will find effective usage of multi core machines for application logic developed using .NET Framework 4 parallel APIs and see significant improvement in application performance.

Advantages of Parallel Programming for developers

With this article, I intended to bring to your notice that, each one of us needs to understand and start using this knowledge in applications. Going forward all servers will have multicore and we will not use that multicore power unless we consider this while development.
There are some cautions that we should be aware of.
  • Considering Overheads
Parallel execution doesn’t come for free. There are overhead costs associated with setting up and managing parallel programming features. If you have only a small amount of work to perform, the overhead can outweigh the performance benefit.
  • Coordinating Data
If your pieces of work share common data or need to work in a concerted manner, you will need to provide coordination. As a general rule, the more coordination leads, the poorer the performance of your parallel program.
  • Scaling Applications
Adding a second core or CPU might increase the performance of your parallel program, but it is unlikely to double it. Likewise, a four-core machine is not going to execute your parallel program four times as quickly. You can expect a significant improvement in performance, but it won’t be 100 percent per additional core, and there will almost certainly be a point at which adding additional cores or CPUs doesn’t improve the performance at all.

Multithreading vs Parallel programming


What is Parallelism? Parallelism is taking a certain task and dividing it into a set of related tasks to be executed concurrently. Sweet! So again, thinking of these tasks as threads, Parallel Programming still has the same problems of concurrent programming (deadlocks, data races, etc...), and introduces new challenges, most notably, sharing and partitioning data across these related threads. This makes Parallel Programming even more difficult and debugging even more complicated :
(
However, it is not all bad news. .NET 4.0 parallel programming is a great step onwards. The new API solves a lot of problems (but not all) of Parallel Programming, and greatly eases up parallel debugging...

The Parallel Programming model of .NET 4.0 is composed of the following:
  • The Task Parallel Library (TPL): this is the base of the Task-based programming discussed in the previous section. It consists of:
    • Task class: the unit of work you will code against instead of the previous thread model.
    • Parallel class: a static class that exposes a task-based version of some parallel-nature problems. More specifically, it contains the following methods:
      • For
      • Foreach
      • Invoke
  • Parallel LINQ (PLINQ): built on top of the TPL and exposes the familiar LINQ as Parallel extensions.


Parallel programming is the general discipline of doing multiple computations in parallel, e.g. using multiple cores, each of which is doing some subcomputation of a larger single problem.

Multithreading is the approach of using multiple threads of execution to process different operations, e.g. if you have two things to do, use one thread to do one and another thread to do the other.

An operating system is able to take each of these threads and other multiplex them onto the same core or to run them in parallel on multiple cores that may exist.

As such, multithreading is a common approach to parallel programming, whereby you can split a larger problem into multiple subproblems and use multiple threads (i.e. multithreading) to process those subproblems concurrently.

Multi-threaded programming is the way which allows developers to take advantage of multiple threads concurrently. And while it has been available for many years, multi-threaded programming has often been avoided due to its complexity. Developers had to put most of their effort in writing clean multi-threaded code rather than focusing on the business problem.

What does multithreading have to do with multi-cores? Can't we write multi-threaded code if we have a single core? Yes, we can. But again, as long as we have a single core, only one thread at a time will work since all threads belong to that same single core... logical enough. When your multi-threaded program runs on a multi-core machine, threads belonging to different cores will be able to run together and hence your program will take advantage of the hardware power.

One final note before going on: multithreaded programming does not differ if you have a multi-core machine or multi-processer machine. This is a hardware separation; underneath, your code will be working with threads all the same.


Multi-threaded example:
public class Test{
    static void Main()
    {
        Counter foo = new Counter();
        ThreadStart job = new ThreadStart(foo.Count);
        Thread thread = new Thread(job);
        thread.Start();

        for (int i=0; i < 5; i++)
        {
            Console.WriteLine ("Main thread: {0}", i);
            Thread.Sleep(1000);
        }
    }}public class Counter{
    public void Count()
    {
        for (int i=0; i < 10; i++)
        {
            Console.WriteLine ("Other thread: {0}", i);
            Thread.Sleep(500);
        }
    }}
Example of parallel:
int n = ...Parallel.For(0, n, i =>{
   // ... });

Thread vs task in c#


First ans

Thread is a lower-level concept: if you're directly starting a thread, you know it will be a separate thread, rather than executing on the thread pool etc.
Task is more than just an abstraction of "where to run some code" though - it's really just "the promise of a result in the future". So as some different examples:
  • Task.Delay doesn't need any actual CPU time; it's just like setting a timer to go off in the future
  • A task returned by WebClient.DownloadStringTaskAsync won't take much CPU time locally; it's representing a result which is likely to spend most of its time in network latency or remote work (at the web server)
  • A task returned by Task.Run() really is saying "I want you to execute this code separately"; the exact thread on which that code executes depends on a number of factors.
Note that the Task<T> abstraction is pivotal to the async support in C# 5.
In general, I'd recommend that you use the higher level abstraction wherever you can: in modern C# code you should rarely need to explicitly start your own thread.


Second ANS

ask is a higher level concept and that means:
  1. You can't use Abort/ThreadAbortedException, you should support cancel in your "business code" periodically testing IsCancellationRequested flag (and for this manage timeoutless connections otherwise you will never get a chance to test a flag).
  2. Also there are no thread.Suspend and thread.Resume methods functionality.
  3. But you have two new tools: continuations, and Nested/Child Tasks
Those two samples demonstrate the syntax:
Task.Factory.ContinueWhenAll(
                            tasks,
                            () =>
                            {
                                int answer = tasks[0].Result + tasks[1].Result;
                                Console.WriteLine("The answer is {0}", answer);
                            });

//StartNew - starts task immediately, parent ends whith child
var parent = Task.Factory.StartNew(() => 
    {
        var child = Task.Factory.StartNew(() =>
        {
            //...
        });
    },  TaskCreationOptions.AttachedToParent);


 3Rd ANS

Suppose you are running a book delivery company. You have four cars and four drivers. A car is a thread, a driver is a processor, and a book delivery is a task. The problem you face is how to efficiently schedule the drivers and cars so that the tasks get done as quickly as possible.
Where things get weird is when there are more cars (threads) than drivers (processors). What happens then is halfway through a trip the driver parks one car (suspends the thread) and gets into a different car (switches context), drives that one around for a while performing tasks, and then eventually comes back to the first car. Obviously that is not as efficient as one driver staying in one car.
The idea of task-based parallism is to break up the work into small tasks that can produce results in the future, and then efficiently allocate exactly as many threads as there are processors so that you don't waste time context switching. In practice, it usually does not work out that nicely, but that's the idea.
which one is better, task or thread?
The question cannot be answered because it doesn't make any sense. Which is better, a book to deliver to a customer, or a car to deliver it in? A car is a device that can be used to deliver a book; those two things are not things you can sensibly describe as "better" or "worse" than the other. It's like asking "which is better, a hole or a drill?"

 Difference between process and thread


A process is an executing instance of an application. What does that mean? Well, for example, when you double-click the Microsoft Word icon, you start a process that runs Word. A thread is a path of execution within a process. Also, a process can contain multiple threads. When you start Word, the operating system creates a process and begins executing the primary thread of that process.
It’s important to note that a thread can do anything a process can do. But since a process can consist of multiple threads, a thread could be considered a ‘lightweight’ process. Thus, the essential difference between a thread and a process is the work that each one is used to accomplish. Threads are used for small tasks, whereas processes are used for more ‘heavyweight’ tasks – basically the execution of applications.
Another difference between a thread and a process is that threads within the same process share the same address space, whereas different processes do not. This allows threads to read from and write to the same data structures and variables, and also facilitates communication between threads. Communication between processes – also known as IPC, or inter-process communication – is quite difficult and resource-intensive.


1. Threads are easier to create than processes since they 
don't require a separate address space.
      
2. Multithreading requires careful programming since threads 
share data strucures that should only be modified by one thread
at a time.  Unlike threads, processes don't share the same 
address space.
      
3.  Threads are considered lightweight because they use far 
less resources than processes.
      
4.  Processes are independent of each other.  Threads, since they 
share the same address space are interdependent, so caution 
must be taken so that different threads don't step on each other.  
This is really another way of stating #2 above.
      
5.  A process can consist of multiple threads.


MultiThreading

Threads, of course, allow for multi-threading. A common example of the advantage of multithreading is the fact that you can have a word processor that prints a document using a background thread, but at the same time another thread is running that accepts user input, so that you can type up a new document.
If we were dealing with an application that uses only one thread, then the application would only be able to do one thing at a time – so printing and responding to user input at the same time would not be possible in a single threaded application.
Each process has it’s own address space, but the threads within the same process share that address space. Threads also share any other resources within that process. This means that it’s very easy to share data amongst threads, but it’s also easy for the threads to step on each other, which can lead to bad things.


Multithreaded programs must be carefully programmed to prevent those bad things from happening. Sections of code that modify data structures shared by multiple threads are called critical sections. When a critical section is running in one thread it’s extremely important that no other thread be allowed into that critical section. This is called synchronization, which we wont get into any further over here. But, the point is that multithreading requires careful programming.
Also, context switching between threads is generally less expensive than in processes. And finally, the overhead (the cost of communication) between threads is very low relative to processes.

C# Lock

Locking is essential in threaded programs. It restricts code from being executed by more than one thread at the same time. This makes threaded programs reliable. The lock statement uses a special syntax form to restrict concurrent access.
Keywords
Note: Lock is compiled into a lower-level implementation based on threading primitives.

Example

NoteHere we see a static method "A" that uses the lock statement on an object. When the method A is called many times on new threads, each invocation of the method accesses the threading primitives implemented by the lock.
Then: Only one method A can call the statements protected by the lock at a single time, regardless of the thread count.
Program that uses lock statement: C#

using System;
using System.Threading;

class Program
{
    static readonly object _object = new object();

    static void A()
    {
 // Lock on the readonly object.
 // ... Inside the lock, sleep for 100 milliseconds.
 // ... This is thread serialization.
 lock (_object)
 {
     Thread.Sleep(100);
     Console.WriteLine(Environment.TickCount);
 }
    }

    static void Main()
    {
 // Create ten new threads.
 for (int i = 0; i < 10; i++)
 {
     ThreadStart start = new ThreadStart(A);
     new Thread(start).Start();
 }
    }
}

Possible output of the program

28106840
28106949
28107043
28107136
28107246
28107339
28107448
28107542
28107636
28107745

In this example, the Main method creates ten new threads, and then calls Start on each one. The method A is invoked ten times, but the tick count shows the protected method region is executed sequentially—about 100 milliseconds apart.
ThreadStart Sleep
Note: If you remove the lock statement, the methods will be executed all at once, with no synchronization.
Static Method

Intermediate representation


Let's examine the intermediate representation for the lock statement in the above example method A. In compiler theory, high-level source texts are translated to lower-level streams of instructions.
Intermediate Language
Tip: The lock statement here is transformed into calls to the static methods Monitor.Enter and Monitor.Exit.
Also: The lock is actually implemented with a try-finally construct. This uses the exception handling control flow.
Try Finally
Intermediate representation for method using lock

.method private hidebysig static void A() cil managed
{
    .maxstack 2
    .locals init (
 [0] object obj2)
    L_0000: ldsfld object Program::_object
    L_0005: dup
    L_0006: stloc.0
    L_0007: call void [mscorlib]System.Threading.Monitor::Enter(object)
    L_000c: ldc.i4.s 100
    L_000e: call void [mscorlib]System.Threading.Thread::Sleep(int32)
    L_0013: call int32 [mscorlib]System.Environment::get_TickCount()
    L_0018: call void [mscorlib]System.Console::WriteLine(int32)
    L_001d: leave.s L_0026
    L_001f: ldloc.0
    L_0020: call void [mscorlib]System.Threading.Monitor::Exit(object)
    L_0025: endfinally
    L_0026: ret
    .try L_000c to L_001f finally handler L_001f to L_0026
}

Relativity


By using the lock statement to synchronize accesses, we are creating a communication between time and state. The state is connected to the concept of time and sequential accesses to the lock.
In the Theory of Relativity, there is also a communication between time and state. This is the speed of light, which is a constant based on the relation of time and space. This connection is present also in locks—in threading constructs.
Tip: For a better description of how relativity mirrors concurrent synchronization, please see the wizard book.
Structure and Interpretation of Computer Programs

Summary

We examined the lock statement in the C# language, first seeing its usage in an example program, and then describing this synchronization. Next, we stepped into the intermediate representation and its meaning in compiler theory.
Finally: We related the Theory of Relativity and the complexities of the physical universe to the lock statement.

C# Async, Await

Threading is complex. The async and await keywords, added in .NET 4.5, help reduce the syntax complexity of threading. We use async on a method declaration. We use await to wait for an async method to return.
Tip: An async method can return only void or a Task.
A Task returns no value.
A Task<int> returns an element of type int.
Void
Tip 2: The Main method cannot be async.
It cannot use the await keyword.
It must start an async method with the Task class.
Tip 3: An async method will be run synchronously if it does not contain the await keyword.
Based on:

.NET 4.5

Example

Maze: complexityThis program uses the async and await keywords to asynchronously run a method. The program begins a long-running method (HandleFileAsync). It displays a status message after this method starts.
And: When the method ends, the results of the computation are written to the screen.
The only difference between this program and a single-threaded one is that we can do something (such as write a message) on the original thread after the async method starts. It avoids blocking the original thread.

To start, we create a Task instance with the ProcessDataAsync method as the argument. We Start this task, and Wait for it to finish. In ProcessDataAsync, we call the HandleFileAsync method. We write a status message to the screen.
Finally: In HandleFileAsync, we use the StreamReader type and await the ReadToEndAsync method. We perform some computations.
Program that uses async, await, Task: C#

using System;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
 // Create task and start it.
 // ... Wait for it to complete.
 Task task = new Task(ProcessDataAsync);
 task.Start();
 task.Wait();
 Console.ReadLine();
    }

    static async void ProcessDataAsync()
    {
 // Start the HandleFile method.
 Task<int> task = HandleFileAsync("C:\\enable1.txt");

 // Control returns here before HandleFileAsync returns.
 // ... Prompt the user.
 Console.WriteLine("Please wait patiently " +
     "while I do something important.");

 // Wait for the HandleFile task to complete.
 // ... Display its results.
 int x = await task;
 Console.WriteLine("Count: " + x);
    }

    static async Task<int> HandleFileAsync(string file)
    {
 Console.WriteLine("HandleFile enter");
 int count = 0;

 // Read in the specified file.
 // ... Use async StreamReader method.
 using (StreamReader reader = new StreamReader(file))
 {
     string v = await reader.ReadToEndAsync();

     // ... Process the file data somehow.
     count += v.Length;

     // ... A slow-running computation.
     //     Dummy code.
     for (int i = 0; i < 10000; i++)
     {
  int x = v.GetHashCode();
  if (x == 0)
  {
      count--;
  }
     }
 }
 Console.WriteLine("HandleFile exit");
 return count;
    }
}

Output: initial

HandleFile enter
Please wait patiently while I do something important.

Output: final

HandleFile enter
Please wait patiently while I do something important.
HandleFile exit
Count: 1916146
In this example, the slow computation done in HandleFileAsync is only for demonstration. It does nothing useful. If you change the string "C:\enable1.txt" to a large text file that exists on your computer, the program should work.

Discussion


Async and await are a code pattern—they allow methods to run on separate threads. They are a form of syntactic sugar. They make code that uses threads easier to read. And this in turn makes that code less prone to flaws.
However: There are many complexities in using async and await. We must return the a Task or void type from an async method.
And: Async methods that are incorrect will cause Visual Studio to report warnings or errors.
Types (StreamReader, HttpClient) contain "Async" methods. These should be called with the await keyword. And the await keyword must be used within an async method. The first async method call can occur with the Task Start method.
StreamReader HttpClient
Also: Event handlers can be used with async methods.
This is not currently shown here.

Summary

A program can create threads in many ways. The Thread type is only one option—async and await provides a new option. Other alternatives, such as BackgroundWorker, ThreadPool, and parallel LINQ expressions, remain available.

C# Sleep

Sleep pauses programs. It receives a value indicating the number of milliseconds to wait. This can be useful for waiting on an external application or task. It does not cause CPU usage during the pause.

Example

Sleep is found on the Thread class. It is a static method that receives one parameter. You must either include System.Threading or use the fully qualified name for the method invocation, which is System.Threading.Thread.Sleep.

Tip: You do not need to create a new Thread to use the Sleep method as it is static.
Static Method
Next: This example shows the runtime behavior of the Thread.Sleep method in the .NET Framework.
Program that sleeps: C#

using System;
using System.Diagnostics;
using System.Threading;

class Program
{
    static void Main()
    {
 //
 // Demonstrates three different ways of calling Sleep.
 //
 var stopwatch = Stopwatch.StartNew();
 Thread.Sleep(0);
 stopwatch.Stop();
 Console.WriteLine(stopwatch.ElapsedMilliseconds);
 Console.WriteLine(DateTime.Now.ToLongTimeString());

 stopwatch = Stopwatch.StartNew();
 Thread.Sleep(5000);
 stopwatch.Stop();
 Console.WriteLine(stopwatch.ElapsedMilliseconds);
 Console.WriteLine(DateTime.Now.ToLongTimeString());

 stopwatch = Stopwatch.StartNew();
 System.Threading.Thread.Sleep(1000);
 stopwatch.Stop();
 Console.WriteLine(stopwatch.ElapsedMilliseconds);

 //
 // Bonus: shows SpinWait method.
 //
 stopwatch = Stopwatch.StartNew();
 Thread.SpinWait(100000 * 10000);
 stopwatch.Stop();
 Console.WriteLine(stopwatch.ElapsedMilliseconds);
    }
}

Output

0              ElapsedMilliseconds after Sleep(0)
8:14:43 AM     Time after Sleep(0)
4999           ElapsedMilliseconds after Sleep(5000)
8:14:48 AM     Time after Sleep(5000)
999            ElapsedMilliseconds after Sleep(1000)
3144           ElapsedMilliseconds after SpinWait(Int32)

The program defines the Main entry point in the Program class, which contains three method invocations to the Thread.Sleep method with varying calling syntaxes and parameters. The results of the Console.WriteLine calls are shown.
Console.WriteLine
Note: The surrounding code around the Sleep invocations takes the system's time and uses Stopwatch to time the Thread.Sleep calls.
Stopwatch

Implementation


Next we review the implementation of the Thread.Sleep method and the Thread.SpinLock method in the .NET Framework. These two methods call into the SleepInternal and SpinWaitInternal functions in mscorlib.
Tip: Thread.Sleep likely will end up calling the same code in the Windows kernel that the Sleep call in any language uses.

Idle loops


When you execute the above program, you will notice that the program does not require significant CPU time when executing the Thread.Sleep calls. It only starts consuming the entire CPU core when the Thread.SpinWait method is invoked.
So: Sleep uses the operating system to "pause" the program, resulting in 0% CPU, while Thread.SpinWait executes useless instructions.
SpinWait

Summary

Thread.Sleep is fairly accurate in pausing the program for the specified number of milliseconds. It does not cause your program to consume 100% CPU. This will save power and provide more resources for other programs.
Finally: We noted the implementation in the .NET Framework and also talked about idle loops and SpinWait.