Why does asynchronous CTP (Async CTP) work that way ?, Asynchronous ctpasync operation
There are many reasons for interest in asynchronous CTP. Asynchronous CTP makes asynchronous programming easier than before. It is not as powerful as Rx, but easier to learn. Asynchronous CTP introduces two new keywords: async and await. The Asynchronous Method (or Lambda expression) must return void, Task, or Task <TResult>. This article is not about asynchronous CTP, because there are many such articles on the Internet. This article aims to focus on some common problems that programmers encounter when starting to use Async CTP.
Inferred return type
When a value is returned from an asynchronous method, the method body returns this value directly, but the method itself is declared as returning a Task <TResult>. When declaring a method that returns type A but must return type B, it is a bit disconnected.
// Actual syntax public async Task <int> GetValue () {await TaskEx. delay (100); return 13; // The return type is "int" instead of "Task <int> "}
Question: Why can't I write this?
// Hypothetical syntax public async int GetValue () {await TaskEx. Delay (100); return 13; // The return type is "int "}
Think: how can we take care of callers in this method? The Asynchronous Method must return the value of the actual result type Task <TResult>. Therefore, the GetValue method returns a smart prompt of the Task <TResult> (this is also true in the Object Browser and Reflector ). At the beginning of the design, it is inferred that the return type has been taken into account, however, the design team has concluded that it is better to maintain this "disconnected connection" in an asynchronous method than to expand this "disconnected connection" on the code base. Such a "disconnected connection" still exists, but it is smaller than before. The consensus of the design team is that consistent method signatures are better. Think: What is the difference between async void and async Task? An async Task method is like any other asynchronous operation, but does not return a value. An async void method acts as an advanced operation. Async Task methods may be combined into other asynchronous methods using await. The async void method may be used as an event handle. The async void method also has other important attributes: in the ASP. NET context, it notifies the web server that the page is complete until it returns. Inferring the return type removes the difference between async void and async Task: either all asynchronous methods are async void (blocking combatability) or all async tasks (blocking them from event handles, at the same time. NET ). There is still a "disconnection" between the type returned by the method declaration and the type returned by the method body ". Another suggestion from the design team is to add a keyword to return to indicate the returned value, but this does not return anything, as shown below:
// Hypothetical syntax public async Task <int> GetValue () {await TaskEx. Delay (100); async return 13; // "async return" means that the value is packaged in Task}
Thinking: convert a large amount of code from synchronous to asynchronous.
The async return keyword is also taken into account, but it is not convincing enough. This is especially true when converting some Synchronous Code into asynchronous code. Forcing people to add asynchronous to each return statement is like "unnecessary busy ". In comparison, it is easier to get used to "disconnected.
Deduce "async"
The async keyword must be used in a method that uses the await keyword. However, if you use async in a method that does not use await, you will also receive a warning.
Q: Why can't async be inferred based on await?
// The hypothetical syntax public Task <int> GetValue () {// "await" implies that this is an "async" method. await TaskEx. Delay (100); return 13 ;}
Thinking: backward compatibility and code readability
The await keyword of a single word is too large to break the changes. The choice between multi-word await (such as await for) or a keyword in an asynchronous method is to enable the await keyword in that method. Obviously, the use of async tagging makes it easier for humans and computers to analyze, so the design team decided to use async/await pairs.
Deduce "await"
Q: Why can't await be inferred based on the existence of async since the display includes async (see above?
// Hypothetical syntax public async Task <int> GetValue () {// implies "await", because this is an "async" method. taskEx. delay (100); return 13 ;}
Thinking: Parallel combinations of asynchronous operations.
At first glance, it seems that await inference simplifies basic asynchronous operations. As long as all the waits can be completed by sequence (such as an operation wait, and then another, and then another), this can work well. However, when someone considers parallel combinations, it crashes.
Parallel combinations in asynchronous CTP use the TaskEx. WhenAny and TaskEx. WhenAll methods. This is a simple example. This method immediately starts two operations and waits for them to complete.
// Actual syntax public async Task <int> GetValue () {// asynchronously retrieve the values of the two parts. // note that they are not waiting for the "not await" Task <int> part1 = GetValuePart1 (); task <int> part2 = GetValuePart2 (); // wait until their values arrive. Await TaskEx. whenAll (part1, part2); // calculate our result int value1 = await part1; // actually not waiting for int value2 = await part2; // actually not waiting for return value1 + value2 ;}
To process parallel combinations, we must be able to say that we will not await an expression.