Friday 15 May 2020

Async and Await Theory


What is Task in C#? ( ref: https://www.csharpstar.com/tasks-csharp/)

 
.NET framework provides Threading.Tasks class to let you create tasks and run them asynchronously. A task is an object that represents some work that should be done. The task can tell you if the work is completed and if the operation returns a result, the task gives you the result.
C# task object typically executes asynchronously on a thread pool thread rather than synchronously on the main application thread.
 
Task And Thread In C#

What is Thread?

 
.NET Framework has thread-associated classes in System.Threading namespace.  A Thread is a small set of executable instructions.
Task And Thread In C#

Why we need Tasks
 
It can be used whenever you want to execute something in parallel. Asynchronous implementation is easy in a task, using’ async’ and ‘await’ keywords.
    Why we need a Thread
     
    When the time comes when the application is required to perform few tasks at the same time.
     

    Properties of Task Class:

    PropertyDescription
    ExceptionReturns any exceptions that caused the task to end early
    StatusReturns the Tasks status
    IsCancelledReturns true if the Task was cancelled
    IsCompletedReturns true if the task is completed successfully
    IsFaultedReturns true if the task is stopped due to unhandled exception
    FactoryProvides acess to TaskFactory class. You can use that to create Tasks

     

    Methods in Task Class :

    MethodsPurpose
    ConfigureAwaitYou can use Await keyword for the Task to complete
    ContinueWithCreates continuation tasks.
    DelayCreates a task after specified amount of time
    RunCreates a Task and queues it to start running
    RunSynchronouslyRuns a task Synchronously
    StartStarts a task
    WaitWaits for the task to complete
    WaitAllWaits until all tasks are completed
    WaitAnyWaits until any one of the tasks in a set completes
    WhenAllCreates a Task that completes when all specified tasks are completed
    WhenAnyCreates a Task that completes when any specified tasks completes

     

    How to create a Task

    1. static void Main(string[] args) {  
    2.     Task < string > obTask = Task.Run(() => (  
    3.         return“ Hello”));  
    4.     Console.WriteLine(obTask.result);  

    How to create a Thread

    1. static void Main(string[] args) {  
    2.     Thread thread = new Thread(new ThreadStart(getMyName));  
    3.     thread.Start();  
    4. }  
    5. public void getMyName() {} 

    Differences Between Task And Thread

     
    Here are some differences between a task and a thread.
    1. The Thread class is used for creating and manipulating a thread in Windows. A Task represents some asynchronous operation and is part of the Task Parallel Library, a set of APIs for running tasks asynchronously and in parallel.
    2. The task can return a result. There is no direct mechanism to return the result from a thread.
    3. Task supports cancellation through the use of cancellation tokens. But Thread doesn't.
    4. A task can have multiple processes happening at the same time. Threads can only have one task running at a time.
    5. We can easily implement Asynchronous using ’async’ and ‘await’ keywords.
    6. A new Thread()is not dealing with Thread pool thread, whereas Task does use thread pool thread.
    7. A Task is a higher level concept than Thread.
    8. One of the major difference between task and thread is the propagation of exception. While using thread if we get the exception in the long running method it is not possible to catch the exception in the parent function but the same can be easily caught if we are using tasks.

    Asyn & await in C# with example

    When using async and await the compiler generates a state machine in the background.

    Here's an example on which I hope I can explain some of the high-level details that are going on:

    public async Task MyMethodAsync()
    {
        Task<int> longRunningTask = LongRunningOperationAsync();
        // independent work which doesn't need the result of LongRunningOperationAsync can be done here
    
        //and now we call await on the task 
        int result = await longRunningTask;
        //use the result 
        Console.WriteLine(result);
    }
    
    public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation 
    {
        await Task.Delay(1000); // 1 second delay
        return 1;
    }

    OK, so what happens here:

    1. Task<int> longRunningTask = LongRunningOperationAsync(); starts executing LongRunningOperation

    2. Independent work is done on let's assume the Main Thread (Thread ID = 1) then await longRunningTask is reached.

      Now, if the longRunningTask hasn't finished and it is still running, MyMethodAsync() will return to its calling method, thus the main thread doesn't get blocked. When the longRunningTask is done then a thread from the ThreadPool (can be any thread) will return to MyMethodAsync() in its previous context and continue execution (in this case printing the result to the console).

    A second case would be that the longRunningTask has already finished its execution and the result is available. When reaching the await longRunningTask we already have the result so the code will continue executing on the very same thread. (in this case printing result to console). Of course this is not the case for the above example, where there's a Task.Delay(1000) involved.


    An await expression does not block the thread on which it is executing. Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Control then returns to the caller of the async method. When the task completes, it invokes its continuation, and execution of the async method resumes where it left off. 

    --------------

    For fastest learning..

    • Understand method execution flow(with a diagram): 3 mins

    • Question introspection (learning sake): 1 min

    • Quickly get through syntax sugar: 5 mins

    • Share the confusion of a developer : 5 mins

    • Problem: Quickly change a real-world implementation of normal code to Async code: 2 mins

    • Where to Next?

    Understand method execution flow(with a diagram): 3 mins

    In this image, just focus on #6 (nothing more) enter image description here

    At #6 step: Execution stopped here as it has run out of work. To continue it needs a result from getStringTask(kind of a function). Therefore, it uses an await operator to suspend its progress and give control back(yield) to the caller(of this method we are in). The actual call to getStringTask was made earlier in #2. At #2 a promise was made to return a string result. But when will it return the result? Should we(#1:AccessTheWebAsync) make a 2nd call again? Who gets the result, #2(calling statement) or #6(awaiting statement)

    The external caller of AccessTheWebAsync() also is waiting now. So caller waiting for AccessTheWebAsync, and AccessTheWebAsync is waiting for GetStringAsync at the moment. Interesting thing is AccessTheWebAsync did some work before waiting(#4) perhaps to save time from waiting. The same freedom to multitask is also available for the external caller(all callers in the chain) and this is the biggest plus of this 'async' thingy! You feel like it is synchronous..or normal but it is not.

    Remember, the method was already returned(#2), it cannot return again(no second time). So how will the caller know? It is all about Tasks! Task was passed. Task was waited for (not method, not value). Value will be set in Task. Task status will be set to complete. Caller just monitors Task(#6). So 6# is the answer to where/who gets the result.

    Thursday 14 May 2020

    Async and await in C#

    First thing: Async will fundamentally change the way most code is written.

    Yup, I believe async/await will have a bigger impact than LINQ. Understanding async will be a basic necessity just a few short years from now.

    Introducing the Keywords

    Let’s dive right in. I’ll use some concepts that I’ll expound on later on - just hold on for this first part.

    Asynchronous methods look something like this:

    public async Task DoSomethingAsync()
    {
      // In the Real World, we would actually do something...
      // For this example, we're just going to (asynchronously) wait 100ms.
      await Task.Delay(100);
    }

    The “async” keyword enables the “await” keyword in that method and changes how method results are handled. That’s all the async keyword does! It does not run this method on a thread pool thread, or do any other kind of magic. The async keyword only enables the await keyword (and manages the method results).

    The beginning of an async method is executed just like any other method. That is, it runs synchronously until it hits an “await” (or throws an exception).

    The “await” keyword is where things can get asynchronous. Await is like a unary operator: it takes a single argument, an awaitable (an “awaitable” is an asynchronous operation). Await examines that awaitable to see if it has already completed; if the awaitable has already completed, then the method just continues running (synchronously, just like a regular method).

    If “await” sees that the awaitable has not completed, then it acts asynchronously. It tells the awaitable to run the remainder of the method when it completes, and then returns from the async method.

    Later on, when the awaitable completes, it will execute the remainder of the async method. If you’re awaiting a built-in awaitable (such as a task), then the remainder of the async method will execute on a “context” that was captured before the “await” returned.

    I like to think of “await” as an “asynchronous wait”. That is to say, the async method pauses until the awaitable is complete (so it waits), but the actual thread is not blocked (so it’s asynchronous).

    Awaitables

    As I mentioned, “await” takes a single argument - an “awaitable” - which is an asynchronous operation. There are two awaitable types already common in the .NET framework: Task<T> and Task.

    There are also other awaitable types: special methods such as “Task.Yield” return awaitables that are not Tasks, and the WinRT runtime (coming in Windows 8) has an unmanaged awaitable type. You can also create your own awaitable (usually for performance reasons), or use extension methods to make a non-awaitable type awaitable.

    That’s all I’m going to say about making your own awaitables. I’ve only had to write a couple of awaitables in the entire time I’ve used async/await. If you want to know more about writing your own awaitables, see the Parallel Team Blog or Jon Skeet’s Blog.

    One important point about awaitables is this: it is the type that is awaitable, not the method returning the type. In other words, you can await the result of an async method that returns Task … because the method returns Task, not because it’s async. So you can also await the result of a non-async method that returns Task:

    public async Task NewStuffAsync()
    {
      // Use await and have fun with the new stuff.
      await ...
    }
    
    public Task MyOldTaskParallelLibraryCode()
    {
      // Note that this is not an async method, so we can't use await in here.
      ...
    }
    
    public async Task ComposeAsync()
    {
      // We can await Tasks, regardless of where they come from.
      await NewStuffAsync();
      await MyOldTaskParallelLibraryCode();
    }

    Tip: If you have a very simple asynchronous method, you may be able to write it without using the await keyword (e.g., returning a task from another method). However, be aware that there are pitfalls when eliding async and await.

    Return Types

    Async methods can return Task<T>, Task, or void. In almost all cases, you want to return Task<T> or Task, and return void only when you have to.

    Why return Task<T> or Task? Because they’re awaitable, and void is not. So if you have an async method returning Task<T> or Task, then you can pass the result to await. With a void method, you don’t have anything to pass to await.

    You have to return void when you have async event handlers.

    You can also use async void for other “top-level” kinds of actions - e.g., a single “static async void MainAsync()” for Console programs. However, this use of async void has its own problem; see Async Console Programs. The primary use case for async void methods is event handlers.

    Returning Values

    Async methods returning Task or void do not have a return value. Async methods returning Task<T> must return a value of type T:

    public async Task<int> CalculateAnswer()
    {
      await Task.Delay(100); // (Probably should be longer...)
    
      // Return a type of "int", not "Task<int>"
      return 42;
    }

    This is a bit odd to get used to, but there are good reasons behind this design.

    Context

    In the overview, I mentioned that when you await a built-in awaitable, then the awaitable will capture the current “context” and later apply it to the remainder of the async method. What exactly is that “context”?

    Simple answer:

    1. If you’re on a UI thread, then it’s a UI context.
    2. If you’re responding to an ASP.NET request, then it’s an ASP.NET request context.
    3. Otherwise, it’s usually a thread pool context.

    Complex answer:

    1. If SynchronizationContext.Current is not null, then it’s the current SynchronizationContext. (UI and ASP.NET request contexts are SynchronizationContext contexts).
    2. Otherwise, it’s the current TaskScheduler (TaskScheduler.Default is the thread pool context).

    What does this mean in the real world? For one thing, capturing (and restoring) the UI/ASP.NET context is done transparently:

    // WinForms example (it works exactly the same for WPF).
    private async void DownloadFileButton_Click(object sender, EventArgs e)
    {
      // Since we asynchronously wait, the UI thread is not blocked by the file download.
      await DownloadFileAsync(fileNameTextBox.Text);
    
      // Since we resume on the UI context, we can directly access UI elements.
      resultTextBox.Text = "File downloaded!";
    }
    
    // ASP.NET example
    protected async void MyButton_Click(object sender, EventArgs e)
    {
      // Since we asynchronously wait, the ASP.NET thread is not blocked by the file download.
      // This allows the thread to handle other requests while we're waiting.
      await DownloadFileAsync(...);
    
      // Since we resume on the ASP.NET context, we can access the current request.
      // We may actually be on another *thread*, but we have the same ASP.NET request context.
      Response.Write("File downloaded!");
    }

    This is great for event handlers, but it turns out to not be what you want for most other code (which is, really, most of the async code you’ll be writing).

    Avoiding Context

    Most of the time, you don’t need to sync back to the “main” context. Most async methods will be designed with composition in mind: they await other operations, and each one represents an asynchronous operation itself (which can be composed by others). In this case, you want to tell the awaiter to not capture the current context by calling ConfigureAwait and passing false, e.g.:

    private async Task DownloadFileAsync(string fileName)
    {
      // Use HttpClient or whatever to download the file contents.
      var fileContents = await DownloadFileContentsAsync(fileName).ConfigureAwait(false);
    
      // Note that because of the ConfigureAwait(false), we are not on the original context here.
      // Instead, we're running on the thread pool.
    
      // Write the file contents out to a disk file.
      await WriteToDiskAsync(fileName, fileContents).ConfigureAwait(false);
    
      // The second call to ConfigureAwait(false) is not *required*, but it is Good Practice.
    }
    
    // WinForms example (it works exactly the same for WPF).
    private async void DownloadFileButton_Click(object sender, EventArgs e)
    {
      // Since we asynchronously wait, the UI thread is not blocked by the file download.
      await DownloadFileAsync(fileNameTextBox.Text);
    
      // Since we resume on the UI context, we can directly access UI elements.
      resultTextBox.Text = "File downloaded!";
    }

    The important thing to note with this example is that each “level” of async method calls has its own context. DownloadFileButton_Click started in the UI context, and called DownloadFileAsync. DownloadFileAsync also started in the UI context, but then stepped out of its context by calling ConfigureAwait(false). The rest of DownloadFileAsync runs in the thread pool context. However, when DownloadFileAsync completes and DownloadFileButton_Click resumes, it does resume in the UI context.

    A good rule of thumb is to use ConfigureAwait(false) unless you know you do need the context.

    Async Composition

    So far, we’ve only considered serial composition: an async method waits for one operation at a time. It’s also possible to start several operations and await for one (or all) of them to complete. You can do this by starting the operations but not awaiting them until later:

    public async Task DoOperationsConcurrentlyAsync()
    {
      Task[] tasks = new Task[3];
      tasks[0] = DoOperation0Async();
      tasks[1] = DoOperation1Async();
      tasks[2] = DoOperation2Async();
    
      // At this point, all three tasks are running at the same time.
    
      // Now, we await them all.
      await Task.WhenAll(tasks);
    }
    
    public async Task<int> GetFirstToRespondAsync()
    {
      // Call two web services; take the first response.
      Task<int>[] tasks = new[] { WebService1Async(), WebService2Async() };
    
      // Await for the first one to respond.
      Task<int> firstTask = await Task.WhenAny(tasks);
    
      // Return the result.
      return await firstTask;
    }
    

    By using concurrent composition (Task.WhenAll or Task.WhenAny), you can perform simple concurrent operations. You can also use these methods along with Task.Run to do simple parallel computation. However, this is not a substitute for the Task Parallel Library - any advanced CPU-intensive parallel operations should be done with the TPL.

    Guidelines

    Read the Task-based Asynchronous Pattern (TAP) document. It is extremely well-written, and includes guidance on API design and the proper use of async/await (including cancellation and progress reporting).

    There are many new await-friendly techniques that should be used instead of the old blocking techniques. If you have any of these Old examples in your new async code, you’re Doing It Wrong(TM):


    Old

    New
    Description
    task.Waitawait taskWait/await for a task to complete
    task.Resultawait taskGet the result of a completed task
    Task.WaitAnyawait Task.WhenAnyWait/await for one of a collection of tasks to complete
    Task.WaitAllawait Task.WhenAllWait/await for every one of a collection of tasks to complete
    Thread.Sleepawait Task.DelayWait/await for a period of time
    Task constructorTask.Run or TaskFactory.StartNewCreate a code-based task

    Baisic Useful Git Commands

      Pushing a fresh repository Create a fresh repository(Any cloud repository). Open terminal (for mac ) and command (windows) and type the be...