Asynchronously according to our usual way of thinking, the computer should finish one thing and then do the next thing. In terms of this, the way to perform a task is called Synchronous Execution (synchronous Execution). In that case, why introduce the concept of asynchronous execution?
Directory
Why to use asynchronous calls
Steps and mechanisms for implementing asynchronous invocations
Why to use asynchronous calls (asynchronous method Execution)
According to our usual way of thinking, the computer should finish one thing and then do the next thing. In terms of this, the way to perform a task is called Synchronous Execution (synchronous Execution). In that case, why introduce the concept of asynchronous execution? The reason is simple, because synchronous execution in some cases does not work well and does not fulfill our intended purpose. Give two simple examples to illustrate the problem.
A. A client Side program will retrieve a complex collection of data from the background database. Perhaps the database operation itself is time-consuming, or it may be a slow network transmission, in short, this method call may take 20 seconds. If you use synchronous calls, the user must be patient and do nothing until the database results are returned. At this point you may want the call to take place somewhere else, and the program will return immediately so that you can do other work. When the data is returned, it is followed by the corresponding operation. In this case, you need to make an asynchronous call to the method of the database operation.
B. An online ticket query subscription program. When the client inquires all the tickets from Beijing to Chicago, the program may be in the background through the Web service to the U.S. Northwest Airlines, China International Airlines and Oriental airlines to visit. The airline tickets for these companies are aggregated and returned to the user as HTML. If it is a synchronous call, then a Web service call is required one after another. If each call takes 10 seconds, then the whole process will take 30 seconds. If you use an asynchronous call, you can make a request to three companies at the same time, and 10 seconds later, when the results come back from three different sites, you can summarize and return to each user. In this way, the whole process takes only about 10 seconds.
See here you may say that this question is nothing new. I can use threads (thread) to achieve this effect in C++,java. Indeed, most advanced languages allow you to create new threads to implement such calls manually. But these manual operation is more complex, the programmer needs to control the thread creation, the destruction, the coordination and so on many details work, easy to produce the mistake. And in large server-side programs, manual control threads are sometimes less performance-optimized, unable to dynamically and intelligently optimize the number of threads depending on the processor situation of the current specific server. For this reason,. NET creates a relatively simple asynchronous method invocation mechanism that makes the problem easier. That's what we're going to talk about today. Use a delegate (delegates) to make an asynchronous call to a method. (This article takes vb.net to demonstrate, C # asynchronous call and this is similar, no longer give a routine)
Steps and mechanisms for implementing asynchronous invocations
Suppose there is a method that accepts the name of a class and then queries the database to return a list of all the students in the class.
Class DemoClass
Public shared Function getstudentslist (ClassName as String)
As String ()
' Querying the Database
' Other operations
End Function
End Class
If you make an asynchronous call to such a method, you first need to define a representative (Delegate) with the same method signature (Function Signature), such as
Delegate Function getstudentlistdelegate (ClassName As String) as String ()
Next, you need to generate a representative instance (Instance) and then "bundle" the representative with your real method, such as
Dim delegate as Getstudentlistdelegate
Getstudentlistdelegate = AddressOf democlass.getstudentslist
(For simplicity, a static method is used here, which is not necessarily necessary)
When you do this,. NET compiler in the background for your representative added a number of methods, they are invoke, BeginInvoke, EndInvoke.
If you use the Invoke method, the effect is a synchronous call, such as
Delegate. Invoke ("Class90")
In this case, the representative passes the input parameter "CLASS90" to the method Getstudentslist, and then returns the return value of the method to the user. The use of this method is synchronous, not what we expect. If the asynchronous effect is to be achieved, we will use BeginInvoke and EndInvoke.
Let's see BeginInvoke first.
Your method of use may look like the following:
Dim ar as System. IAsyncResult
Ar = delegate. BeginInvoke ("Class90", nothing, Nothing)
You may find that this invocation method is somewhat different. First, there are two more input parameters, followed by the return value of system. IAsyncResult. What the hell is going on here?
When you call BeginInvoke, a series of things happen automatically in the background.
When you use a delegate to make a call request, the CLR (the common language runtime, Common Language Runtime) receives the request and places the request in an internal processing queue (queue). Once the placement is complete, the CLR immediately returns a IAsyncResult object to the caller. This object is very important and we have to explain his specific role in a moment.
When the caller receives the returned IAsyncResult object, it can proceed to the next step. Because putting a request into a queue is a very quick operation, the caller can immediately complete the next action without being "blocked".
The CLR maintains a "thread pool" in the background. These threads are waiting for the processing queue mentioned earlier. Once a task is placed in the queue, a thread gets the task and executes it. That is, the time-consuming operation of the original caller thread is done by a thread in the thread pool. (You can see here that there must be other threads in the asynchronous call, no matter what language is used.) Either you create it manually (such as Java), or the system creates for you (such as. NET). So how many threads does this "thread pool" have? This problem you can not care about. The CLR determines itself based on the characteristics of the program and the current hardware conditions. For example, for a generic desktop program running on a single-processor platform, the thread pool may have several threads, while for a background application running on a 4-processor server, the thread pool may have hundreds of threads. The benefit of this is to reduce the programmer's development difficulty and let the. NET CLR address these issues unrelated to the user's application logic. )
Since threads in the thread pool are replacing the method call (getstudentslist), how do we know when this call in the background is complete? This method calls the value returned (here is a list of students) how do we get it? Here we will use the IAsyncResult object that we mentioned earlier.
This IAsyncResult object is a "receipt", through which you can query whether the background call is complete or not. If it's done, you can use it to retrieve the results you want.
Dim ar as System.IAsyncResult
Ar = delegate. BeginInvoke ("Class90", nothing, Nothing)
' * * * some other operations
。。。
' * * * check background call status
If (AR. iscompleted) Then
' * * * Retrieve the result of the asynchronous calling method
End If
If the backend call is over, you can use the EndInvoke of the representation to get the return value.
Dim Students as String ()
Students = delegate. EndInvoke (AR)
So what happens if you use EndInvoke directly without testing whether the backend call is over or not? If the background call is not completed, the EndInvoke call is "blocked" until the background call completes before returning. If there is an exception in the background call, then EndInvoke can also catch this exception
Dim Students as String ()
Trystudents = delegate. EndInvoke (AR)
Catch ex as Exception
' Handle this exception
End Try
Since the EndInvoke call will be "blocked" (if the background asynchronous call is not completed), how does the CLR handle the following complex case?
Dim ar1, ar2 as System.IAsyncResult
Dim Rt1, Rt2 as String ()
AR1 = delegate1. BeginInvoke ("Class90", nothing, Nothing)
AR2 = Delegate2. BeginInvoke ("class94", nothing, Nothing)
Rt1 = delegate1. EndInvoke (AR1)
Rt2 = Delegate2. EndInvoke (AR2)
In this example, the delegate1 invocation and the DELEGATE2 call completion order may be in a variety of situations. For example, delegate2 after the call to the first, then EndInvoke is the use of the order is not very important? In fact, you can ignore this problem and the CLR will guarantee that you can do the following after two asynchronous calls are over. As for how it is achieved, you can not take care of it.
In fact, EndInvoke is very important. If you use BeginInvoke, you'd better use EndInvoke. Because if you don't use EndInvoke, the exception that is invoked in the background has no chance of being captured. In addition, EndInvoke allows the CLR to release resources used in an asynchronous invocation, or your application may have a resource leak (Resource leak).
Here, the situation has been more clear. Using delegate allows the background thread to do time-consuming operations instead of the current thread, so that the current thread is not "blocked" and can do other work immediately. However, if the current thread passes the EndInvoke to get the result of an asynchronous call, it is likely to be "blocked". It looks a bit like "tearing down the east wall robbing", as if we didn't get any benefit. For example, you have to go to the copy room to copy a batch of materials, which takes one hours. A synchronous call means you have to copy it yourself and return to the office for another job one hours later. An asynchronous call means you can hand in the copy to the copy room, where someone is responsible for the copy. You can go back to the office and do other work after you drop the material. But the problem is, you have to constantly check whether the material is copied, once the copy is completed, immediately back to the corresponding operation. You keep looking at it (calling the Iscomplete method) or "Wait" (calling the Representative's EndInvoke method) actually "tied" you up, and you haven't been able to do anything else. Can I leave the material in the copy room, and then they'll send me the material back after the copy is ready? The answer is yes, that is, using the callback function (Callback functions).
Remember that example in front of us, when we call BeginInvoke with the representative, we have two more arguments, one of which is the callback function, and the other is the parameter that executes the callback function. The callback function means the function (or method) that is automatically executed after the background line finishes executing the method of the asynchronous call. You can also specify parameters when executing this callback function. Also say, you have the copy room copy clerk to complete the copy, put the material back to your desk, and every 10 pages a stack. This "put on the desk" is the callback function, and "every 10 pages per stack" is the parameter used when the callback function executes.
' parameter of the callback function
Dim myvalue as Integer = 10
' The definition of the callback function
Sub Puttodesk (Byval ar as IAsyncResult)
Dim x As Integer = CInt (ar. asyncstate) ' Get the parameters
' The appropriate action
End Sub
' Ways to use callback functions
Private callbackdelegate as AsyncCallback = AddressOf Puttodesk
...
Dim ar as System.IAsyncResult
Ar = delegate. BeginInvoke ("Class90", Callbackdelegate, MyValue)
When using callback functions, be aware that your callback function must be and. NET system-defined AsyncCallback, that is, your callback function must have the same signature as the AsyncCallback. That is, it must be a subroutine (sub Procedure), and a IAsyncResult class object must be an input parameter.
Note that the callback function is performed by a background thread (which is what we call a copy clerk). This method of implementation can in some cases cause a small problem. For example, in Windows desktop applications there is a rule that all changes (appearance and attributes) of user interface elements must be created by these interface elements (in terms of the interface main thread, Primary UI thread). If other threads attempt to update the interface elements, there will be unpredictable consequences. If you violate this principle, then your program in theory is unsafe, even if the problem you have not found.
In the example above, if a background thread gets the student list from the database, it is likely that the callback function it is going to perform is a drop-down list (Dropdown list) on the update interface, or a table (grid) or something. But doing so violates what we call the thread principle of the interface update. So what do we do?
In fact, this problem is not difficult to solve, designers in the design. NET, the problem has been taken into account. The specific solution I will introduce in the next article.
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.