神刀安全网

async & await keyword in C#

In this article, we will discuss:

  • What is an async Method?
  • The Flow of Control in an Async Method
  • The await Expression
  • Exception Handling and the await Expression
  • Cancelling an async Operation
  • Waiting Asynchronously for Tasks in the async Method
  • Summary

What is an async Method?

An async method is a method that returns to the calling method before completing all its work, and then completes its work while the calling method continues its execution.

An async method has the following characteristics:

  • An async method must have the async keyword in its method header, and it must be before the return type.
  • This modifier doesn’t do anything more than signal that the method contains one or more await expressions.
  • It contains one or more await expressions. These expressions represent tasks that can be done asynchronously.
  • It must have one of the following three return types.
    − void :If the calling method just wants the async method to execute, but doesn’t need any further interaction with it
    − Task : If the calling method doesn’t need a return value from the async method, but needs to be able to check on the async method’s state
    − Task<T> :If the calling method is to receive a value of type T back from the call, the return type of the async method must be Task
  • An async method can have any number of formal parameters of any types but it cannot be out or ref parameters.
  • The name of an async method should end with the suffix Async.
  • Otherthan Methods, lambda expressions and anonymous methods can also act as async objects.

Using an async method that returns a Task<int> object:

class Program   {       static void Main()       {           Task<int> value = DoAsyncWork.CalculateSumAsync(10, 11);           //Do Other processing           Console.WriteLine("Value: {0}", value.Result);               }   }       static class DoAsyncWork     {         public static asyncTask<int> CalculateSumAsync(int i1,int i2)          {             int sum = awaitTask.Run(() => GetSum(i1,i2));             return sum;         }           private static int GetSum(int i1, int i2)         {         return i1+i2;         }     } 

Output:

Using an async method that returns a Task object:

class Program   {       static void Main()       {           Taskvalue = DoAsyncWork.CalculateSumAsync(10, 11);           //Do Other processing           value.Wait();           Console.WriteLine("Async stuff is done");               }   }       static class DoAsyncWork     {         public static asyncTaskCalculateSumAsync(int i1,int i2)          {             int sum = awaitTask.Run(() => GetSum(i1,i2));             Console.WriteLine("Value: {0}", sum);         }           private static int GetSum(int i1, int i2)         {         return i1+i2;         }     } 

Output:

Value: 21

Async stuff is done

Using an async method that returns a void object:

 class Program   {       static void Main()       {           DoAsyncWork.CalculateSumAsync(10, 11);           //Do Other processing           Thread.Sleep(200);           Console.WriteLine("Program Exiting");               }   }       static class DoAsyncWork     {         public static asyncvoid CalculateSumAsync(int i1,int i2)          {             int sum = awaitTask.Run(() => GetSum(i1,i2));             Console.WriteLine("Value: {0}", sum);         }           private static int GetSum(int i1, int i2)         {         return i1+i2;         }     } 

Output:

Value: 21

Program Exiting

The Flow of Control in an Async Method :

The body of an async method has divided mainly into three sections.

async &amp; await keyword in C#

  • Before the first await expression : This includes all the code at the beginning of the method up until the first await expression. This section contains very minimal code that doesn’t require too much processing.
  • The await expression : This expression represents the task to be performed asynchronously.
  • Continuation : This is the rest of the code in the method, following the await expression. This includes the information about which thread it’s on, the values of the variables currently in scope, and other things it’ll need in order to resume execution later, after the await expression completes

async &amp; await keyword in C#

The code in the async method does the following:

  • It executes, asynchronously, its await expression’s awaitable task.
  • When the await expression is done, it executes the continuation.
  • The continuation itself might have other await expressions, which are handled the same way. That is, the await expression is executed asynchronously, followed by the execution of its continuation.
  • When the continuation encounters a return statement or the end of the method:
    • If the method’s return type is void, the flow of control exits.
    • If the method’s return type is Task, the continuation sets the status properties on the Task and exits. If the return type is a Task<T>, the continuation additionally sets the Result property of the Task object.

The await Expression:

The await expression specifies a task to be done asynchronously.

Syntax:

awaittask 

There are now a number of BCL methods that return objects of type Task<T>, you’ll most likely have your own methods that you want to use as the task for an await expression. The easiest way to do that is to create a Task from your method using the Task.Run method.

the most important fact about the Task.Run method is that it runs your method on a different thread.

One signature of the Task.Run method is,it takes a Func
delegate as a parameter.

TaskRun( Func<TReturn> func ) 

So, to pass your method to the Task.Run method, you need to create a delegate from it.

There are three ways to do this.

In the code, method Get20 has a form compatible with a Func<int> delegate since it takes no parameters and returns an int.

  • In the first instance, which is in the first two lines of method DoWorkAsync, a Func delegate named twenty is created using Get20. That delegate is then used in the Task.Run method in the next line.
  • In the second instance, a Func delegate is created right in the Task.Run method’s parameter list.
  • The last instance doesn’t use the Get20 method at all. It uses the return statement that comprises the body of the Get20 method, and uses it as the body of a lambda expression compatible with a Func<int> delegate. The lambda expression is implicitly converted to the delegate.
    class MyClass     {         public int Get20() // Func<int> compatible         {             return 20;         }         public asyncTaskDoWorkAsync()         {             Func<int> twenty = new Func<int>(Get20);             int a = awaitTask.Run(twenty);             int b = awaitTask.Run(new Func<int>(Get20));             int c = awaitTask.Run(() => { return 20; });             Console.WriteLine("{0} {1} {2}", a, b, c);         }         class Program         {             static void Main()             {                 Task t = (new MyClass()).DoWorkAsync();                 t.Wait();             }         }     } 

Exception Handling and the await Expression:

You can use await expression inside atry statement.

class Program     {         static void Main(string[] args)         {             Task t = BadAsync();             t.Wait();             Console.WriteLine("Task Status : {0}", t.Status);             Console.WriteLine("Task IsFaulted: {0}", t.IsFaulted);         }         static asyncTaskBadAsync()         {             try             {                 awaitTask.Run(() => { throw new Exception(); });             }             catch             {                 Console.WriteLine("Exception in BadAsync");             }         }     } 

Output:

Exceptionin BadAsync TaskStatus : RanToCompletion TaskIsFaulted: False 

Cancelling an async Operation :

You can cancel your own async operation.There are two classes in the System.Threading.Tasks namespace that are designed for this purpose: CancellationToken and CancellationTokenSource.

  • A CancellationToken object contains the information about whether a task should be cancelled or not.
  • A task that has a CancellationToken object needs to periodically inspect it to see what the token’s state is. If the CancellationToken object’s
    IsCancellationRequested property is set to true, the task should halt its operations and return.
  • A CancellationToken is nonreversible and can only be used once. That is, once it’s IsCancellationRequested property is set to true, it can’t be changed.
  • A CancellationTokenSource object creates a CancellationToken object, which can then be given to various tasks. Any objects holding a cancellationTokenSource can call its Cancel method, which sets the CancellationToken’s IsCancellationRequested property to true.
  class Program     {         static void Main()         {             CancellationTokenSourcects = new CancellationTokenSource();             CancellationTokentoken = cts.Token;             MyClassmc = new MyClass();             Task t = mc.RunAsync(token);             //Thread.Sleep( 3000 ); // Wait 3 seconds.             //cts.Cancel(); //cancel the operation.             t.Wait();             Console.WriteLine("Was Cancelled: {0}", token.IsCancellationRequested);         }     }     class MyClass     {         public asyncTaskRunAsync(CancellationTokenct)         {             if (ct.IsCancellationRequested)                 return;             awaitTask.Run(() => CycleMethod(ct), ct);         }         void CycleMethod(CancellationTokenct)         {             Console.WriteLine("Starting CycleMethod");             const int max = 5;             for (int i = 0; i < max; i++)             {                 if (ct.IsCancellationRequested) // Monitor the CancellationToken.                     return;                 Thread.Sleep(1000);                 Console.WriteLine(" {0} of {1} iterations completed", i + 1, max);             }         }     } 

Output:

StartingCycleMethod 1 of 5 iterationscompleted 2 of 5 iterationscompleted 3 of 5 iterationscompleted 4 of 5 iterationscompleted 5 of 5 iterationscompleted WasCancelled: False 

If you uncomment the Thread.Sleep and Cancel statements in method Main, the task is cancelled after three secondsand below is the output:

StartingCycleMethod 1 of 5 iterationscompleted 2 of 5 iterationscompleted 3 of 5 iterationscompleted WasCancelled: True 

Waiting Asynchronously for Tasks in the async Method:

In your async method, if you want to wait on Tasks as your await expression. This allows your async method to return to the calling method, but allows the async method to wait for completion of one or all of a set of tasks. The calls that allow this are the Task.WhenAll and Task.WhenAny methods.

 class MyDownloadString     {         public void DoRun()         {             Task<int> t = CountCharactersAsync("http://www.csharpstar.com", "http://www.techkatak.com");             Console.WriteLine("DoRun: Task {0}Finished", t.IsCompleted ? "" : "Not ");             Console.WriteLine("DoRun: Result = {0}", t.Result);         }         private asyncTask<int> CountCharactersAsync(string site1, string site2)         {             WebClientwc1 = new WebClient();             WebClientwc2 = new WebClient();             Task<string> t1 = wc1.DownloadStringTaskAsync(new Uri(site1));             Task<string> t2 = wc2.DownloadStringTaskAsync(new Uri(site2));             List<Task<string>> tasks = new List<Task<string>>();             tasks.Add(t1);             tasks.Add(t2);             awaitTask.WhenAll(tasks);             Console.WriteLine(" CCA: T1 {0}Finished", t1.IsCompleted ? "" : "Not ");             Console.WriteLine(" CCA: T2 {0}Finished", t2.IsCompleted ? "" : "Not ");             return t1.IsCompleted ? t1.Result.Length : t2.Result.Length;         }     }     class Program     {         static void Main()         {             MyDownloadStringds = new MyDownloadString();             ds.DoRun();         }     } 

Output:

DoRun: TaskNot Finished CCA: T1Finished CCA: T2Finished DoRun: Result = 105212 

Summary:

In this article, we have discussed:

  • What is an async Method?
  • The Flow of Control in an Async Method
  • The await Expression
  • Exception Handling and the await Expression
  • Cancelling an async Operation
  • Waiting Asynchronously for Tasks in the async Method
  • Summary

You may also like:

Thanks for visiting !!

© 2016,admin. All rights reserved.

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » async & await keyword in C#

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址