Monday, February 18, 2013

C#.net - Asynchronous Programming with Async and Await

When your user interface is unresponsive or your server does not scale, chances are your code needs to be more asynchronous. Microsoft .NET Framework 4.5 introduces new language features in C# and Visual Basic to provide a new foundation for asynchronous in .NET programming. This new foundation makes asynchronous programming very similar to synchronous programming.

There are several ways of doing asynchronous programming in .Net.  Visual Studio 2012 introduces a new approach using the ‘Async’ and ‘Await’ keywords.  These tell the compiler to construct task continuations in quite an unusual way.


Asynchronous operations are operations that are initiated and continue running concurrently with the invoking code.

When conforming to the .NET Task-Based Asynchronous Pattern (TAP), asynchronous methods return a task, which represents the ongoing operation and enables you to wait for its eventual outcome.


Use Task and Task<TResult> types from System.Threading.Tasks namespace to represent arbitrary asynchronous operations.

When invoking a task and its completion is expected, use the keyword "await" when you call a method. Use the syntax:

await MethodAsync();

In this way the code flow does not stop. No need to assign methods to events, even more, there is no callbacks because now the compiler is responsible for creating them.

Async and Await keywords

The async keyword can be used as a modifier to a method or anonymous method to tell the C# compiler that the respective method holds an asynchronous operation in it.

The await keyword  is used while invoking the async method, to tell the compiler that the remaining code in that particular method should be executed after the asynchronous operation is completed.

Return Type

The return type of an asynchronous method must be Task,Task <T> or Void.

In an asynchronous function with void return type or Task, return statements should not be an expression.

When the return type is Task <T> return statements should have an expression that is implicitly convertible to T.

Let see  how you can use async and await generate a small program that allows us to see the effect of TAP pattern.

Step 1
Create a WPF Application and give the solution name as SolAsynchronousSample.

Step 2
Add a TextBox and Two Button on Window,it is look like this
<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="3*"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        
        <TextBox x:Name="txtMessage" Grid.Row="0" Grid.Column="0" AcceptsReturn="True" TextWrapping="Wrap" IsReadOnly="True" Background="Black" Foreground="Green"></TextBox>
        <Button x:Name="btnFiles" Content="Get Files" Grid.Row="1" Grid.Column="0" Height="32" Margin="320,23,117,23" Click="btnFiles_Click" />
        <Button x:Name="btnDateTime" Content="Get Date_Time" Grid.Row="1" Grid.Column="0" Height="32" Margin="410,23,10,23" Click="btnDateTime_Click" />
        
    </Grid>


Click on Image for better View.

Step 3
In Code Behind,Write a Async Method to get file name from Directory,it is look like this
/// <summary>
        /// Get List of Files
        /// </summary>
        /// <returns>List</returns>
        private Task<List<String>> GetFilesAsync()
        {
            try
            {
                return Task.Run(() =>
                {
                    // Get Files Name from Specify Directory
                    return System.IO.Directory.GetFiles(@"C:\Windows\System32").ToList();
                });
              
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message); 
            }
        }

Step 4
In Code Behind,Write a Print Method to Bind File Names in TextBox Control,it is look like this
/// <summary>
        /// Print File Name in textBox
        /// </summary>
        /// <param name="FileName">specify the File Name</param>
        private void PrintFilesList(String FileName)
        {
            try
            {
                txtMessage.Text = txtMessage.Text + FileName + System.Environment.NewLine;
                txtMessage.ScrollToEnd();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);  
            }
        }


Step 5
Double-click on the button to generate a btnFiles_Click event handler and add async modifier,add the follwing code,it is look like this
private async void btnFiles_Click(object sender, RoutedEventArgs e)
        {
            try
            {

                btnFiles.IsEnabled = false;

                // Call GetFilesAsync Method with await Keyword
                List<String> ListFilesObj = await GetFilesAsync();

                // Check the List Object is Null or Not
                if (ListFilesObj != null)
                {
                    // Check the List Object Count is grether than 1 or not
                    if (ListFilesObj.Count >= 1)
                    {
                        foreach (String Item in ListFilesObj)
                        {
                            // Call PrintFilesList Method (Bind File Name in textBox)
                            PrintFilesList(Item);

                            // task that will complete after a time delay
                            await Task.Delay(100);
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                btnFiles.IsEnabled = true;
            }
        }


async modifier tells to compiler that this method contains code that will run asynchronously using await keyword. 

We can await the method lower down the call stack because it now returns a task we can await on.  What this means in practice is that the code sets up the task and sets it running and then we can await the results from the task when it is complete anywhere in the call stack.  This gives us a lot of flexibility as methods at various points in the stack can carry on executing until they need the results of the call.

Step 6
Double-click on the button to generate a btnDateTime_Click event handler and add the following Code,it is look like this 
private void btnDateTime_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                MessageBox.Show(System.DateTime.Now.ToString()); 
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message); 
            }
        }

Run the application, press the button Get Files and check that the application is not frozen and is receptive. You can now press the Get DateTime button without having to wait the end of the period.

if we use Synchronous Programming way then our application will freezes and we can not press the Get DateTime button until the first process not end.

I hope you understand now why asynchronous Programming  is Important.

Output


Click on Image for better View.

Download
Download Source Code

3 comments:

  1. Good explanation.. Asynch method and await keyword.

    Ragards
    - Shashikant Patil

    ReplyDelete
  2. Nice post!! Thanks for putting the efforts on gathering useful content and sharing here. You can find more .Net programming related question and answers in the below forum.

    .Net programming question and answers

    ReplyDelete