Friday, April 13, 2012

C# 4.5 | Asynchronous Programming in the .NET Framework 4.5

Content

- Asynchronous Operations
- Async - Task-based Asynchronous Pattern -
    Task and Task<IResult>
    async
    await
    Requirements to use Async
  - Example using async and await
       First example: Creating the synchronous implementation
       Second example: Creating the asynchronous application

Asynchronous tasks are necessary when applications are frozen due to actions that do not stop and let the user continue using them, you have probably seen the message "Application not responding ...". Let's see how to solve this problem with a new feature of Framework 4.5.

Asynchronous operations

A computer has a fixed number of processors and each of these processors can perform only one operation at a time, let's call this operation thread. Each thread in an application is programmed to run on the processor for a period of time.

If a code performs some I / O action, the thread is suspended until the device has completed its work. If you have a very slow task it can start working on a separate thread and get the result of the operation once the task is completed. While the separate thread running the application can perform other tasks unrelated to the task of long duration. Thus, we can isolate the work they do homework.

Most methods are called synchronous, which means that the method is completed in the current thread. However, some methods are called asynchronous which means that the current thread begins execution of the method in another thread and the call returns immediately. Synchronous methods are known as block because the thread that calls the method does other work until the method completes.

Here is how to call another task using a wire with framework 2.0

namespace Threads
{
    class Program
    {
        static void Main(string[] args)
        {
            //Create a threar to call the SlowTask method
            System.Threading.Thread task =
                new System.Threading.Thread(
                    new System.Threading.ParameterizedThreadStart(SlowTask));
            //Start the task
            task.Start(900);
            //Task is stopped?
            if (task.ThreadState != System.Threading.ThreadState.Stopped)
                System.Console.WriteLine("Task is still running");
            //Actual thread stops until the other task stops
            //or until 1000 milliseconds are reached
            tarea.Join(1000);
            //Ask again - Task is stopped?
            if (task.ThreadState != System.Threading.ThreadState.Stopped)
                System.Console.WriteLine("1 second and task is still running");
            else
                System.Console.WriteLine("Finally, the task is stopped!");
            System.Console.ReadLine();
        }

        /// <summary>
        /// Method that last param milliseconds
        /// </summary>
        /// <param name="param"></param>
        static void SlowTask(object param)
        {
            //param as int
            int gap = (int)parametro;
            //Wait some time
            System.Threading.Thread.Sleep(gap);
            System.Console.WriteLine("This slow task has ended.");
        }
    }
}


For more information about threads go to::
http://msdn.microsoft.com/en-us/library/6kac2kdh.aspx
 
Changes to data are also time-consuming resulting in a poor user experience. Another way to use alternate tasks using threads is to use a BackgroundWorker object as shown below.

namespace SampleBackgroundWorker
{
    class Program
    {
        static void Main(string[] args)
        {
            //Create BackgroundWorker object
            System.ComponentModel.BackgroundWorker task =
                new System.ComponentModel.BackgroundWorker();
            //Attach anonymous code to delegate
            task.DoWork += (o, params) =>
            {
                //Simulate a 1 second gap
                System.Threading.Thread.Sleep(1000);
                //Use Result to fill it with a value (date)
                params.Result = System.DateTime.Now;
            };
            //Get results
            task.RunWorkerCompleted += (o, params) =>
            {
                if (params.Error != null)
                {//Show error message
                    System.Console.WriteLine("Error raised");
                }
                else
                {//Show success message
                    System.Console.WriteLine("Success!");
                    //Write value to screen
                    System.Console.WriteLine(parametros.Result.ToString());
                }

            };
            //Start task
            task.RunWorkerAsync();
            System.Console.ReadLine();
        }
    }
}


It starts to look very complicated and we always need a method or block of code that responds to events "DoWork" and "CompletedWork".

Async - Asynchronous Pattern

When using the pattern-based asynchronous tasks. NET Framework 4.5 (TAP) asynchronous methods return a Task object representing the task. 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 myMethodAsync();

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.

Task and Task<IResult>

The return type of an asynchronous method must be void, Task or Task <T>. The return type of an anonymous function is the type of return (if any) of the delegate.

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.

async

Conventionally asynchronous methods use the Async suffix to indicate that execution can be carried out after the method has ended.

An async method provides a convenient way to do things that take a long time without causing blockages in the calling thread. The thread that makes an async method call can continue without having to wait until the method finishes.

await

An expression await is only allowed when it is within an asynchronous method. Commonly, a modified method for the modifier async contains at least one instruction await. Such a method runs synchronously until it meets the first expression await, at which execution is suspended until the task ends.

 

Requirements to use Async

Async is available in the Beta version of Visual Studio 11 or as a download CTP (Community Technology Preview) for Visual Studio 2010 SP1.

Example using async and await

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

First exercise: Creating the synchronous implementation

Task 1 - Create an application synchronously.
1.     Start Visual Studio 11 and created a new WPF application in C # called SampleAsync.
2.      Change the properties of the main window to have a size of 480 by 480 pixels.
3.      Add two buttons and a ListBox. Name the controls. ButtonRead, ButtonMessage and FileList, respectively..
4.     Arrange the components so that they have the following appearance:




5.   Open the file in C # code associated with MainWindow and add the following code just below the constructor.

private IEnumerable<string> GetFiles()
        {
var files = from file
in
System.IO.Directory.GetFiles(@"C:\Windows\System32")
select file;
System.Threading.Thread.Sleep(5000);
            return files;
        }

6.       Double-click on the button to generate a ButtonRead_Click event handler and add the following code.

private void ButtonRead_Click(object sender, RoutedEventArgs e)
        {
ButtonRead.IsEnabled = false;
FileList.ItemsSource = GetFiles();
ButtonRead.IsEnabled = true;
        }

7.     Return to design mode and double-click on ButtonMessage to generate the Click event handler. Next, add the following code to the generated method.

private void ButtonMessage_Click(object sender, RoutedEventArgs e)
        {
           MessageBox.Show("Local time: " +
DateTime.Now.ToLongTimeString());
        }

8.      Run the application and press the Files button. Note that the application freezes and you can not press the Time button. After 5 seconds the ListBox is populated with the files in the directory and theTime button is functional and displays the message.



Exercise Two: Creating the asynchronous application

 

Task 1 - Modify the method GetFiles to be asynchronous.
1.      Go to the contents of this method and modify its structure so that the return data type changes from IEnumerable<String> to Task<IEnumerable<String>> and the name of the method now has the suffix "Async" as shown.

private Task<IEnumerable<String>> GetFilesAsync()

2.      Now wrap the code in the method to return an object of type Task.

private Task<IEnumerable<String>> GetFilesAsync()
        {
                return Task.Run(() =>
            {
                  System.Threading.Thread.Sleep(5000);
                  var files = from file in
  System.IO.Directory.GetFiles(@"C:\Windows\System32")
  select file;
                  return files;
            });
        }

Task 2 - Modify the Click event handler to be able to make asynchronous calls..
1.      Change the structure of the method by adding the async modifier as shown.

private async void ButtonRead_Click(object sender, RoutedEventArgs e)

2.      Now modify the method call, to be done through an asynchronous call using the keyword x as a modifier of the method call. Remember that we have already changed the name of the method by adding the suffix Asycn. 

FileList.ItemsSource = await GetFilesAsync();

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

 

In this second example we have created an application that does not freeze its operation for initiating a call to a method.

References:


1 comment:

Anonymous said...

Hi, after reading this remarkable piece of writing i am as well happy to share my experience here with mates.
Also see my web site > How to stop your bike being stolen