Async and await keywords

Source: Internet
Author: User

Async and await are introduced in C #5.0. These two keywords allow you to write asynchronous code in synchronous mode more conveniently. That is to say, more convenient asynchronous programming. The general format is as follows:

 
 
  1. var result = await expression
  2. statement(s); 

This statement is equivalent:

 
 
  1. var awaiter = expression.GetAwaiter(); 
  2. awaiter.OnCompleted (() => 
  3. var result = awaiter.GetResult(); 
  4. statement(s); 
  5. ); 

The expression here is generally a Task or Task <TResult>, but in fact you can define some objects that can use await. However, certain conditions must be met. Let's first look at an example.

 
 
  1. Static void Main (string [] args)
  2. {
  3. DisplayPrimesCount ();
  4. Thread. Sleep (5000); // wait until asynchronous execution is completed
  5. }
  6. Static Task <int> GetPrimesCountAsync (int start, int count)
  7. {
  8. Return Task. Run () =>
  9. ParallelEnumerable. Range (start, count). Count (n =>
  10. Enumerable. Range (2, (int) Math. Sqrt (n)-1). All (I => n % I> 0 )));
  11. }
  12. Static async void DisplayPrimesCount ()
  13. {
  14. Int result = await GetPrimesCountAsync (2, 1000000); // Blocking
  15. Console. WriteLine (result );
  16. }

This is a common method.

To asynchronously execute the GetPrimesCountAsync method, first GetPrimesCountAsync must return a "Waiting" object. In the above Code, GetPrimesCountAsync returns the Task <int> type. Then, the async keyword must be added to the await method. And we can see await GetPrimesCountAsync (2, 1000000); this statement returns int instead of Task <int>.

The above code is described in the natural language as follows:

When DisplayPrimesCount is called, DisplayPrimesCount runs a new Task, which calculates the number of prime numbers. After the calculation is completed, the calculated value is returned, and the returned value is placed in the Task object, and returned to the caller. After obtaining the Task value, the caller obtains the result value of the Task.

When the program logic encounters the await GetPrimesCountAsync method, the thread will be suspended until the asynchronous operation is completed. After the result value is obtained, the program will continue to run.

In essence, the emergence of await and async is only a syntactic sugar, but this syntactic sugar can make asynchronous programming more elegant, directly abandoning the original EAP and APM such everywhere BeginXXX, the ugly EndXXX mode increases productivity.

You can use the await method. The returned value must be an awaitable object. It is troublesome to customize an awaitable object. An object must meet the following conditions:

Because Microsoft does not provide an interface that meets the preceding conditions, you can implement this interface by yourself.

 
 
  1. public interface IAwaitable<out TResult> 
  2.     { 
  3.         IAwaiter<TResult> GetAwaiter(); 
  4.     } 
  5.     public interface IAwaiter<out TResult> : INotifyCompletion // or ICriticalNotifyCompletion 
  6.     { 
  7.         bool IsCompleted { get; } 
  8.         TResult GetResult(); 
  9.     } 

As lambda expressions cannot directly use await, you can program and implement this function skillfully. For example, to implement the extension method on a Func delegate, note:The extension method must be defined in the top-level static class..

 
 
  1. Public static class FuncExtensions
  2. {
  3. Public static IAwaiter <TResult> GetAwaiter <TResult> (this Func <TResult> function)
  4. {
  5. Return new FuncAwaiter <TResult> (function );
  6. }
  7. }
  8. Public interface IAwaitable <out TResult>
  9. {
  10. IAwaiter <TResult> GetAwaiter ();
  11. }
  12. Public interface IAwaiter <out TResult>: INotifyCompletion // or icriticalpolicycompletion
  13. {
  14. Bool IsCompleted {get ;}
  15. TResult GetResult ();
  16. }
  17. Internal struct FuncAwaitable <TResult>: IAwaitable <TResult>
  18. {
  19. Private readonly Func <TResult> function;
  20. Public FuncAwaitable (Func <TResult> function)
  21. {
  22. This. function = function;
  23. }
  24. Public IAwaiter <TResult> GetAwaiter ()
  25. {
  26. Return new FuncAwaiter <TResult> (this. function );
  27. }
  28. }
  29. Public struct FuncAwaiter <TResult>: IAwaiter <TResult>
  30. {
  31. Private readonly Task <TResult> task;
  32. Public FuncAwaiter (Func <TResult> function)
  33. {
  34. This. task = new Task <TResult> (function );
  35. This. task. Start ();
  36. }
  37. Bool IAwaiter <TResult>. IsCompleted
  38. {
  39. Get
  40. {
  41. Return this. task. IsCompleted;
  42. }
  43. }
  44. TResult IAwaiter <TResult>. GetResult ()
  45. {
  46. Return this. task. Result;
  47. }
  48. Void INotifyCompletion. OnCompleted (Action continuation)
  49. {
  50. New Task (continuation). Start ();
  51. }
  52. }
  53. You can write the following in main:
  54.  
  55. Static void Main (string [] args)
  56. {
  57. Func () => {Console. WriteLine ("await .."); return 0 ;});
  58. Thread. Sleep (5000); // wait until asynchronous execution is completed
  59. }
  60. Static async void Func (Func <int> f)
  61. {
  62. Int result = await new Func <int> (f );
  63. Console. WriteLine (result );
  64. }

Where:

The Func method can be executed asynchronously, because Func <int> has implemented the extended method GetAwaiter, And the return value type is the IAwaitable type defined by itself.

Of course, the simpler method is to use the Task object provided by Microsoft so that the lambda expression can return the Task type.

 
 
  1. Static void Main (string [] args)
  2. {
  3. Func () =>
  4. {
  5. Return Task <int>. Run <int> () => {return Enumerable. Range (1,100). Sum ();});
  6. });
  7. Thread. Sleep (5000); // wait until asynchronous execution is completed
  8. }
  9. Static async void Func (Func <Task <int> f)
  10. {
  11. Int result = await f ();
  12. Console. WriteLine (result );
  13. }
---------------------------------

References: C #5.0 IN A NUTSHELL

Http://weblogs.asp.net/dixin/archive/2012/11/08/understanding-c-async-await-2-awaitable-awaiter-pattern.aspx

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.