laitimes

C# Asynchronous Programming async and AWAIT Use 1.What are asynchronous methods 2.Asynchronous methods execute on non-UI threads 3.Asynchronous methods execute in UI threads 4.Exception handling

The syntax has the following characteristics:

The method uses async as a modifier

Methods contain one or more await expressions inside

The method return type must be one of void, task, task<t>

The parameters of an asynchronous method can be of any type, but not an out and ref parameter

Conventionally, async methods are suffixed with async.

In addition to methods, lambda expressions and anonymous functions can also be used as asynchronous objects.

Detailed return types:

Task type: If the calling method does not need to return a value from the async method, but needs to check the state of the async method, it can return a task, in which case even if a return statement appears in the async method, nothing will be returned (in fact, there is no need to show using the return statement).

task <t> type, in addition to the function of the task above, you can also return the value of type t through the return attribute.

Void type: If you just execute an asynchronous method without any further interaction with it ("call and forget"), you can use void, and like task, you won't get anything even if you have a return statement (you don't actually need to show using a return statement). Note that async functions with a return value of void cannot be preceded by a await. When calling the other two asynchronous methods with return values, if the await is not used, the compiler will give a warning.

The principle of using the return type:

For methods that need to return an object, use task<t >

When a method belongs to a method that does not care when it is completed after firing, you can use void, such as an event handler.

Returns a task when you do not need to return a result, but you need to know whether to execute the completed method. For example, an asynchronous method involves data update logic, and the method that calls the asynchronous method needs to read the latest data after calling the asynchronous method, which requires the return type with a task, but not with void, otherwise the latest data may not be read.

The creation and use of asynchronous methods consists of three parts:

Calling method: The method calls an asynchronous method and continues execution while the async method executes its task

Asynchronous methods (async)

Await expression: Used inside an asynchronous method to indicate what needs to be executed asynchronously. An asynchronous method can contain as many await expressions, and the compiler issues a warning if none of them contains them

Asynchronous methods consist of three parts:

The part before await

Await expression

Subsequent part: the part after await (if there are multiple awaits, that is the part between the await and after the last await)

Here are a few issues to be aware of:

The parts before await are executed synchronously (before the first await to be exact)

When arati is reached, control of the asynchronous method is returned to the calling method. If the type returned by the method is task or if the task <t >, a task object created (representing tasks to be completed asynchronously and subsequently) is returned to the calling method. The return value here is not the return value of the await expression, but the return value type declared in the asynchronous method (i.e. task or task<t>)

The following work needs to be done inside the asynchronous method:

Asynchronous execution of the await expression is an idle task

When the await expression execution is complete, the subsequent sections are executed. The follow-up itself may also be the await expression, the processing process is consistent with the previous one.

If the subsequent part encounters return or the method reaches the end, it will do the following things: (At this point, it should be noted that it is not that the return value is encountered or the end of the method is reached, and the return value can be obtained, it just exits (the asynchronous task may not be executed yet))

If the returned type is void, the control flow exits

If the returned type is task, the subsequent section sets the properties of the task object and exits

If the returned type is task<t>, set not only the task object property, but also the task property of the task object

The call method continues, obtaining the task object (except void) according to the second step, and when its actual value is needed, referencing the task property in the task object. At that point, if the async method sets the property, the calling method gets its value and continues. Otherwise, wait for the property to be set before proceeding.

C# Asynchronous Programming async and AWAIT Use 1.What are asynchronous methods 2.Asynchronous methods execute on non-UI threads 3.Asynchronous methods execute in UI threads 4.Exception handling

The demo is done in a console application, we can see that the main thread has an id of 10, the first await and the code immediately after the code have thread ids of 6 and 11, the second await and the code immediately after the code have a thread id of 6, the async asynchronous method is executed in a non-ui thread, the asynchronous operation awaited and the code to be executed after that are all fetched from the thread pool by a thread to execute the code, And what you get from the thread pool doesn't have to be the same thread.

C# Asynchronous Programming async and AWAIT Use 1.What are asynchronous methods 2.Asynchronous methods execute on non-UI threads 3.Asynchronous methods execute in UI threads 4.Exception handling

This demo can be seen that when using async asynchronous methods in the UI thread, the code immediately after await will always be executed in the UI thread. Therefore, you need to pay attention to this when using it, and when executing async asynchronous methods in ui and non-ui threads, you need to pay attention to these two details, otherwise it will bring unnecessary trouble, such as:

As the code shows, define an asynchronous method with a return value of task type, first execute this asynchronous method metahodasync1(), and then get the return value of the asynchronous method, in this process of getting the return value, the original thread executing the asynchronous method will also block until the return value is obtained, and the program without accident will output 1 after running for a second. But when it comes to ui threading, it looks like this:

C# Asynchronous Programming async and AWAIT Use 1.What are asynchronous methods 2.Asynchronous methods execute on non-UI threads 3.Asynchronous methods execute in UI threads 4.Exception handling

The same is to define an asynchronous method with a return value of the task type, and the same is to execute the asynchronous method metahodasync1() first, and then get the return value of the asynchronous method, but, here, we use the winform program to execute, the asynchronous method is called on the ui thread, then, now there is a problem, once the button 1 is clicked, the program is stuck.

As mentioned above, the asynchronous method called in the ui thread, after some of the code after its await operation, is still really executed in the ui thread, then, first, click the button button of the button, the asynchronous method executes the asynchronous task in the await, and the calling function continues to execute to the richtextbox1.text = a.result.tostring() This sentence is blocked by the ui thread waiting for the asynchronous result, and after the await task is executed, Return 1 This operation also needs to be executed in the ui thread, but the ui has been blocked and cannot execute any code, just like this, I am waiting for you to return the value, you are waiting for me to release the ui thread to execute the code for you, no one gives in, causing the program to freeze.

In fact, there is a problem with the above writing, and the correct writing below can avoid stuck:

Async task or aync task<t> means that the method actually automatically returns a reference to the operation in progress, which you can then wait for elsewhere. In this returned reference, include the exception object, as well as the result and state of us and so on. The async void, on the other hand, does not have a task object and cannot return these contents. Therefore, there is a difference in exception handling between the two.

1. Async task or aync task<t> exception flow

C# Asynchronous Programming async and AWAIT Use 1.What are asynchronous methods 2.Asynchronous methods execute on non-UI threads 3.Asynchronous methods execute in UI threads 4.Exception handling

The result of the above code is as follows:

C# Asynchronous Programming async and AWAIT Use 1.What are asynchronous methods 2.Asynchronous methods execute on non-UI threads 3.Asynchronous methods execute in UI threads 4.Exception handling

After the exception is thrown again from the async task throwexception(), it is intercepted again at the awaitexception_event() of the calling function, which is the result we expect.

2.task.wait() of the exception stream

Change the code to the following, when calling the tweetception of this task, do not use await, but use wait(), as follows

C# Asynchronous Programming async and AWAIT Use 1.What are asynchronous methods 2.Asynchronous methods execute on non-UI threads 3.Asynchronous methods execute in UI threads 4.Exception handling

Then you get the result like this:

C# Asynchronous Programming async and AWAIT Use 1.What are asynchronous methods 2.Asynchronous methods execute on non-UI threads 3.Asynchronous methods execute in UI threads 4.Exception handling

This is because exceptions are saved inside the task in the aggregateexception object. Each task will store a list of exceptions. When you await a task, the first exception is reshrew, so you can catch the specified exception type (like the invalidationexception). However, when you block the task synchronously using task.wait or task.result, all exceptions are encapsulated and thrown out of the aggregateexception. Exception handling is easier when the await task is visible.

If you compile the program without a hello on line 20, there are two reminders:

warning cs4014: because this call is not awaited, execution of the current method continues before the call is completed. consider applying the 'await' operator to the result of the call.

warning cs1998: this async method lacks 'await' operators and will run synchronously. consider using the 'await' operator to await non-blocking api calls, or 'await task.run(...)' to do cpu-bound work on a background thread.

The runtime found that the results were different, and the abnormality was not received. Of course, the anomaly doesn't disappear out of thin air, but without a hat, the anomaly is like being "swallowed" up. This is because the caller does not have an ideal, does not get the task, and cannot get the exception in the task, and the exception cannot return to the context of the calling code.

C# Asynchronous Programming async and AWAIT Use 1.What are asynchronous methods 2.Asynchronous methods execute on non-UI threads 3.Asynchronous methods execute in UI threads 4.Exception handling

As you can see, calling async task must use await.

3. Async void's exception flow

Change the return type of the storyception to async void. Then the compiler will also tell you not to use await where the storyception is called.

C# Asynchronous Programming async and AWAIT Use 1.What are asynchronous methods 2.Asynchronous methods execute on non-UI threads 3.Asynchronous methods execute in UI threads 4.Exception handling

After running, we get this result, and the anomaly is not "swallowed", but directly thrown out. Try in awaitexception_event... Catch doesn't catch. This is because this method does not have a task, and we cannot arat in the awaitexception_event, so the exception is thrown directly in the current context of the program. Since this is a console program, we can receive this exception if in gui (such as wpf and uwp) programs, in the global unhandled_exception. But if there are multiple such async voids throwing exceptions like this, we can't differentiate them in order to handle them efficiently. It can be seen that using async void is very dangerous behavior, and the use of async void is also avoided in your code (except for asynchronous events or delegates).

C# Asynchronous Programming async and AWAIT Use 1.What are asynchronous methods 2.Asynchronous methods execute on non-UI threads 3.Asynchronous methods execute in UI threads 4.Exception handling

In async, await, the best exception handling is that the asynchronous function uses async task or async task<t>, so that the caller can get a reference to the function through awit, get the result of the period and exception information.

Read on