C #5 explanation of new features-asynchronous programming

Source: Internet
Author: User
Tags call back

In the coming new Windows Runtime, it is more fundamental to determine that no API will run for more than 50 ms. The operation that takes a longer time will be replaced by the 'kick off this operation' API, and will be returned immediately without waiting for the operation result. This is because Microsoft wants the Windows 8 Metro program to be "Fast and mobile" on the instant touch UI ", because even a tiny pause in a touch operation is more obvious than a mouse or keyboard operation. From the UI perspective, this is a very helpful design.

But from the developer's point of view, it will make programming more troublesome. When we read files or call the WCF Service, we usually want to influence the results. If we can ensure that the results can be obtained when reading files or returning from the WCF Service, we can write code that is easy to understand and reason from top to bottom.

String url = ReadUrlFromFile (filename );
String contentOfUrl = HttpGetFromUrl (url );
MessageBox. Show (contentOfUrl );
Such an API is called synchronous or blocking. The synchronous API is easy to understand and use. However, when the current thread in your program does not respond, the API cannot control your code to do other tasks because it cannot deliver results.

The method for using the 'kickoff' API that returns an instant message is called asynchronous or non-blocking. It is more difficult to use Asynchronous API programming because you cannot return results to variables in real time to ensure the running:

String url = BeginReadUrlFromFile (filename); // Won't work -- file read hasn't completed when BeginRead returns
String contentOfUrl = BeginHttpGetFromUrl (url); // Ditto
MessageBox. Show (contentOfUrl );
Instead, you have to call back the code that requires the returned result until it is ready:

BeginReadUrlFromFile (filename, url => {
BeginHttpGetFromUrl (url, contentOfUrl => {
MessageBox. Show (contentOfUrl );
});
});
Even such a simple example is rather ugly. In fact, asynchronous code requires more operations, more complex callbacks, logical conditions, early exits, and error processing .. The real asynchronous API in the. NET Framework is more ugly, and IAsyncResult objects and the EndXxx method calls are everywhere.

However, if we want the program to run in Windows Runtime, this is what the user wants us to do.

Original solution: Use F #

F # smart people come up with the best of both worlds. F # has a special feature called asynchronous workflow, which consists of many blocks of code imported asynchronously. In an asynchronous workflow, you can call an asynchronous method by using a syntax similar to synchronization:

Async {
Let! Url = BeginReadUrlFromFile filename
Let! ContentOfUrl = BeginHttpGetFromUrl url
MessageBox. Show (contentOfUrl)
}
F # The Compiler automatically transforms this easy-to-read and understandable code into a terrible callback equivalent so that you can simply program the Response Behavior of asynchronous calls from top to bottom.

New Solution: use C #5

C # has the same smart people behind it, so the new C # has also implemented this function. The next version of C # included in Visual Studio 11 beta includes two new keywords: "async" and "await"

The keyword "async" indicates that the asynchronous call method is used. This is very important for the caller to understand it, because it means that the method will return before it ends-the method can be abandoned halfway during asynchronous calls and directly returned to the caller.

The keyword "await" indicates that we want to ensure top-down logical asynchronous calls rather than manually writing callback functions. The following is an example of their perfect combination:

Public async void ShowReferencedContent (string filename ){
String url = await BeginReadFromFile (filename );
String contentOfUrl = await BeginHttpGetFromUrl (url );
MessageBox. Show (contentOfUrl );
}
This is more convenient to read, write, and check than callback, but they play the same role. (In fact, this is actually more intelligent than callback, because the compiler will not skip the error state or make a mistake in early exit logic or ignore thread errors because of boredom .)

What happens when we call a method? The first is to call the BeginReadFromFile method, which provides the file name and the callback generated by the compiler. BeginReadFromFile Returns quickly, but the results are still not available. Therefore, the results still cannot be allocated to the URL variable -- part of the callback -- and the method exits and is returned to the caller! Call the function to run it again and keep its code running continuously, even though the called method has not ended.

Then, the file system completes reading later. This means that the result is now available, and the Runtime schedules a callback. This does not necessarily happen immediately-the specific time also depends on the synchronization environment. The callback function is running. Bind the URL variable to the result of the file operation and call BeginHttpGetFromUrl. It will return immediately, that is, the method will exit again.

Finally, the HTTP operation is complete and the callback function is run for the second time. It binds the content of the Url variable and the message box that displays the result (if any ).

What value do I want to return to the caller?

Async methods can exit before they 've finished. so if an async method wants to return a result, it has to recognize that it might return to the caller before that result is available. for this reason, an async method that returns a value has to have a return type of Task rather than a 'proper' value. A Task represents a chunk of work which will eventually deliver a value, so a caller can examine the returned Task to determine when the result becomes available. here's how an async method looks when returning a value:

The Asynchronous Method can exit before the end. Therefore, if an Asynchronous Method wants to return a result, it has to confirm whether it is returned to the caller before the result is obtained. Therefore, the Asynchronous Method of a returned value must contain a Task return type instead of a "suitable" value. A Task means that a large piece of work will be passed in the end, so the caller can stick to the returned Task to determine when the result will be obtained. The following is an Asynchronous Method of returned values:

Public static async Task <string> GetReferencedContent (string filename)
{
String url = await BeginReadFromFile (filename );
String contentOfUrl = await BeginHttpGetFromUrl (url );
Return contentOfUrl;
}
Note: although the return type is Task <string>, the return status receives a string. Again, the compiler manages the returned status to generate a Task.

Now the caller can directly call the GetReferencedContent method, wait for the string to become available, manually wait for it, or make it end early-in any case it is applicable to use results.

Async-friendly APIs

If you are used to asynchronous programming in. NET 4 or earlier versions, you will be accustomed to using the Begin and End methods in pairs, such as WebRequest. BeginGetResponse and WebRequest. EndGetResponse. This still exists in. NET4.5, but they do not use the await keyword. (This is mainly because the BeginXxx method needs to call the exact method in the callback to obtain the result, and the compiler does not rely on the EndXxx naming convention ). NET4.5 provides a new method to return the Task object, so you can call WebRequest. getResponseAsync to replace WebRequest. beginGetResponse method. The following is an example of using asynchronous APIs in. NET4.5:

Private static async Task <string> GetContent (string url)
{
WebRequest wr = WebRequest. Create (url );
Var response = await wr. GetResponseAsync ();
Using (var stm = response. GetResponseStream ())
{
Using (var reader = new StreamReader (stm ))
{
Var content = await reader. ReadToEndAsync ();
Return content;
}
}
}
This works with WebRequest. getResponse () and TextReader. the synchronization code of ReadToEnd () is so similar that you only need to add Async after the API name and the "await" keyword before the method. I believe you will soon be able to master it.


Author Wang ran

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.