[Reading Notes] C # advanced programming Chapter 1 asynchronous programming,

Source: Internet
Author: User

[Reading Notes] C # advanced programming Chapter 1 asynchronous programming,

(1) Importance of asynchronous programming

In asynchronous programming, method calls are run in the background (usually with the help of a thread or task) and do not block the call thread. There are three different asynchronous programming modes: asynchronous mode, event-based asynchronous mode, and the newly added Task-Based asynchronous mode (TAP, which can be implemented using async and await keywords ).

 

 

(2) asynchronous mode

1. Asynchronous Programming Model of C #1 ).

2. C #2 EAP Event-based Asynchronous Pattern based on events ).

3. Task-based Asynchronous Pattern ).

Reference: http://www.cnblogs.com/zhaopei/p/async_one.html

 

 

(3) asynchronous programming Basics

The async and await keywords are only compiler functions. The compiler creates code using the Task class.

 

1. Create a task

1 /// <summary> 2 /// synchronization method 3 /// </summary> 4 /// <returns> </returns> 5 static string SayHi (string name) 6 {7 Thread. sleep (3000); 8 return "Hello! "+ Name; 9} 10 11 /// <summary> 12 // Task-Based asynchronous mode 13 /// </summary> 14 /// <returns> </returns> 15 static task <string> SayHiAsync (string name) 16 {17 return Task. run <string> () =>{ 18 return SayHi (name); 19}); 20}

In the generic version, Task. Run <string> creates a Task that returns a string.

 

2. Call asynchronous Methods

To use the await keyword, you must use the async modifier to declare the method. Before the await method is completed, other code in the method will not be executed, but the thread that calls the method of await will not be blocked.

Private async static void CallerWithAsync () {string result = await SayHiAsync ("zhangsan"); Console. WriteLine (result );}

The async modifier can only be used to return tasks and void methods.

 

3. Continue the task

The ContinueWith method of the Task class defines the code called after the Task is completed. The delegate assigned to the ContinueWith method accepts the input of completed tasks as parameters. The Result attribute can be used to access the results returned by the task.

Private static void CallerWithContinuationTask () {Task <string> t = SayHiAsync (""); t. ContinueWith (_ t => Console. WriteLine (_ t. Result ));}

 

4. Synchronization Context

The WPF Application sets the DispatcherSynchronizationContext attribute, and the WindowsForm application sets the WindowsFormsSynchronizationContext attribute. If the thread that calls the Asynchronous Method is assigned to the synchronization context, await continues to be executed after completion. If you do not use the same context, you must call ConfigureAwait (ContinueOnCapturedContext: false) of the Task class ).

 

5. Use multiple asynchronous Methods

(1) Call asynchronous methods in order

Private async static void MultipleCallerWithAsync () {string result1 = await SayHiAsync ("Zhang San"); string result2 = await SayHiAsync ("Li Si"); Console. writeLine ("two completed greetings! {0} and {1} ", result1, result2 );}

 

(2) Use a bundle

A bundle can accept multiple parameters of the same type and return values of the same type. The Task aggregator accepts multiple Task objects as parameters and returns a Task.

Private async static void MultipleCallerWithAsyncWithCombinators1 () {Task <string> task1 = SayHiAsync ("Zhang San"); Task <string> task2 = SayHiAsync ("Li Si"); await Task. whenAll (task1, task2); Console. writeLine ("two completed greetings! {0} and {1} ", result1, result2 );}

The Task class defines WhenAll (returned only after all tasks are completed) and WhenAny (returned after any Task is completed.

When the return type of a task is the same, the returned results can be accepted using arrays.

Private async static void MultipleCallerWithAsyncWithCombinators2 () {Task <string> task1 = SayHiAsync ("Zhang San"); Task <string> task2 = SayHiAsync ("Li Si "); string [] results = await Task. whenAll (task1, task2); Console. writeLine ("two completed greetings! {0} and {1} ", results [0], results [1]);}

 

6. Convert the asynchronous mode

When some classes do not provide the Task-Based asynchronous mode (only BeginXX, EndXX), you can use the FromAsync method defined by the TaskFactory class to convert the method to the task-based asynchronous mode.

Private static async void ConvertingAsyncPattern () {Func <string, string> method = SayHi; string result = await Task <string>. factory. fromAsync <string> (name, callback, state) =>{ return method. beginInvoke (name, callback, state) ;}, ar =>{ return method. endInvoke (ar) ;}, "Wang Machang", null); Console. writeLine (result );}

 

 

(4) handle errors

1. Asynchronous Method Exception Handling

A better way to handle Asynchronous Method exceptions is to use the await keyword and place it in try/catch statements.

 1 static async Task ThrowAfter(int ms, string message) 2 { 3     await Task.Delay(ms); 4     throw new Exception(message); 5 } 6  7 private static async void HandleOneError() 8 { 9     try10     {11         await ThrowAfter(2000, "first");12     }13     catch (Exception ex)14     {15         Console.WriteLine("handled {0}", ex.Message);16     }17 }

 

2. Exception Handling for multiple asynchronous Methods

When you call two or more methods in sequence that throw an exception, you cannot use the preceding method because when the first Asynchronous Method throws an exception, the remaining methods in the try block will not be called.

If you need to continue executing the remaining methods and then handle the exceptions, you can use the Task. WhenAll method, so that no matter whether the Task throws an exception or not, it will wait until all the tasks are completed. However, you can only see the first exception passed to the WhenAll method.

private static async void HandleOneError(){    try    {        Task task1 = ThrowAfter(1000, "first");        Task task2 = ThrowAfter(2000, "second");        await Task.WhenAll(task1, task2);    }    catch (Exception ex)    {        Console.WriteLine("handled {0}", ex.Message);    }}

If you need to finish executing the remaining methods and get all the thrown exceptions, you can declare the task variable outside the try block so that it can be accessed in the catch Block. In this way, the IsFaulted attribute can be used to check the status of the Task. If the value is true, the Exception. InnerException of the Task class can be used to access the Exception information.

private static async void HandleOneError(){    Task task1 = null;    Task task2 = null;    try    {        task1 = ThrowAfter(1000, "first");        task2 = ThrowAfter(2000, "second");        await Task.WhenAll(task1, task2);    }    catch (Exception ex)    {        if (task1 != null && task1.IsFaulted)        {            Console.WriteLine(task1.Exception.InnerException);        }        if (task2 != null && task2.IsFaulted)        {            Console.WriteLine(task2.Exception.InnerException);        }    }}

 

3. Use aggresponexception Information

To get all the Exception information, you can also write the results returned by Task. WhenAll into a Task variable, and then access the Exception attribute (aggresponexception type) of the Task class ). Aggresponexception defines the InnerExceptions attribute, which contains all the exception information.

private static async void HandleOneError(){    Task task = null;    try    {        Task task1 = ThrowAfter(1000, "first");        Task task2 = ThrowAfter(2000, "second");        await (task = Task.WhenAll(task1, task2));    }    catch (Exception)    {        foreach (var exception in task.Exception.InnerExceptions)        {            Console.WriteLine(exception);        }    }}

 

 

(5) Cancel

1. Cancel the task

Private CancellationTokenSource cts; private void OnCancel () {if (cts! = Null) {cts. Cancel (); // cts. CancelAfter (1000); // Cancel after 1000ms }}

 

2. Use the framework feature to cancel a task

Private async void OnTaskBasedAsyncPattern () {List <string> urlList = new List <string> (); urlList. add ("http://www.baidu.com"); cts = new CancellationTokenSource (); try {foreach (var url in urlList) {Random rd = new Random (); int I = rd. next (1,100); // The number between 1 and 100, if (I % 2 = 0) {OnCancel (); // cancel the task when the random number is an even number} var client = new HttpClient (); var response = await client. getAsync (url, cts. token); // The GetAsync method checks whether the var result = await response operation should be canceled. content. readAsStringAsync (); Console. writeLine (result) ;}} catch (OperationCanceledException ex) // this exception is thrown when the task is canceled {Console. writeLine (ex. message );}}

 

3. Cancel a custom task

The Run method of the Task class provides an overloaded version that passes the CancellationToken parameter. Use the IsCancellationRequest attribute to check the token and the ThrowIfCancellationRequested method to trigger an exception.

Public async void CustomerTask () {cts = new CancellationTokenSource (); var list = new List <string> (); list. add ("1"); list. add ("2"); list. add ("3"); var deal_list = new List <int> (); try {await Task. run () => {foreach (var item in list) {Random rd = new Random (); int I = rd. next (1,100); // The number between 1 and 100, if (I % 2 = 0) {OnCancel (); // cancel the task when the random number is an even number} if (cts. token. isCancellationRequested) {Console. writeLine ("Processing Task exception, rollback"); deal_list.Clear (); cts. token. throwIfCancellationRequested ();} deal_list.Add (Convert. toInt32 (item); Console. writeLine (item) ;}}, cts. token);} catch (OperationCanceledException ex) {Console. writeLine (ex. message );}}

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.