In depth analysis of C asynchronous programming details
- 2020-05-10 18:45:42
- OfStack
The difference between synchronous and asynchronous methods
The synchronized method call needs to wait for the synchronized method to finish executing and return the result before the program can continue
Asynchronous methods are returned immediately after being called so that the program can perform other operations while the called method completes its tasks
Overview of asynchronous programming
.NET Framework allows you to invoke any method asynchronously. Define a delegate that has the same signature as the method you need to call; The common language runtime will automatically have the appropriate signature for the delegate definition
The BeginInvoke and EndInvoke methods.
The BeginInvoke method is used to start the asynchronous call. It has the same parameters as the method you need to execute asynchronously, except for two additional parameters (described later).
BeginInvoke returns immediately, without waiting for the asynchronous call to complete.
BeginInvoke returns IasyncResult, which can be used to monitor the progress of the call.
The EndInvoke method is used to retrieve the results of the asynchronous call. The EndInvoke method can be called at any time after BeginInvoke is called. If the asynchronous call does not complete, EndInvoke blocks 1 straight up to
The asynchronous call completes. The parameters for EndInvoke include the out and ref parameters for the method you want to execute asynchronously (as in Visual Basic) < Out > ByRef and ByRef) and by
BeginInvoke returns IAsyncResult.
Four common methods for making asynchronous calls using BeginInvoke and EndInvoke. After calling BeginInvoke, you can:
1. Do something, then call EndInvoke 1 and block until the call is complete.
2. Get WaitHandle using IAsyncResult.AsyncWaitHandle, use its WaitOne method to perform 1 straight block to emit the WaitHandle signal, and then call
EndInvoke. This is where the main program waits for the asynchronous method and waits for the result of the asynchronous method.
3. Poll IAsyncResult returned by BeginInvoke, IAsyncResult.IsCompeted to determine when the asynchronous call is completed, and then call EndInvoke. This process is personally thought to be related to
The same.
4. Pass the delegate for the callback method to BeginInvoke. This method is executed on the ThreadPool thread after the asynchronous call is completed, and it can call EndInvoke. This is mandatory
Replace the callback function with IAsyncResult.AsyncState (the last parameter of BeginInvoke method) as the delegate, and then use the delegate to execute EndInvoke.
Warning always calls EndInvoke after the asynchronous call completes.
If you don't understand the above, you can understand it later.
example
1) let's start with a simple example of an asynchronous method without a callback function
Please read the comments carefully when you run the program. It is helpful to understand. Also, if you synchronize both of the commented methods, you will find the speed advantage of running asynchronously.
2) let's look at the asynchronous operation of WebRequest and WebResponse with callback functions.
There are callback functions and asynchronous operations in asynchronous callbacks.
First, get ResponseStream asynchronously, and then read the data asynchronously.
This is a classic program. You can learn a lot from it. Let's talk about it together.
conclusion
As mentioned above,.net framework can invoke any method asynchronously. So asynchrony is very useful.
There are also many methods for asynchronous invocation in the.net framework class library. Generally, 1 is the macro representation of asynchronous operation with the beginning of Begin and the end of End forming 1 pair, asynchronous delegate method, plus two callback functions and AsyncState parameters. So to do asynchronous programming, don't forget to delegate delegate, Begin, End, AsyncCallBack delegate, AsyncState instance (cast by IAsyncResult.AsyncState in the callback function), IAsycResult(monitor async), that's enough to understand what async is all about.
The synchronized method call needs to wait for the synchronized method to finish executing and return the result before the program can continue
Asynchronous methods are returned immediately after being called so that the program can perform other operations while the called method completes its tasks
Overview of asynchronous programming
.NET Framework allows you to invoke any method asynchronously. Define a delegate that has the same signature as the method you need to call; The common language runtime will automatically have the appropriate signature for the delegate definition
The BeginInvoke and EndInvoke methods.
The BeginInvoke method is used to start the asynchronous call. It has the same parameters as the method you need to execute asynchronously, except for two additional parameters (described later).
BeginInvoke returns immediately, without waiting for the asynchronous call to complete.
BeginInvoke returns IasyncResult, which can be used to monitor the progress of the call.
The EndInvoke method is used to retrieve the results of the asynchronous call. The EndInvoke method can be called at any time after BeginInvoke is called. If the asynchronous call does not complete, EndInvoke blocks 1 straight up to
The asynchronous call completes. The parameters for EndInvoke include the out and ref parameters for the method you want to execute asynchronously (as in Visual Basic) < Out > ByRef and ByRef) and by
BeginInvoke returns IAsyncResult.
Four common methods for making asynchronous calls using BeginInvoke and EndInvoke. After calling BeginInvoke, you can:
1. Do something, then call EndInvoke 1 and block until the call is complete.
2. Get WaitHandle using IAsyncResult.AsyncWaitHandle, use its WaitOne method to perform 1 straight block to emit the WaitHandle signal, and then call
EndInvoke. This is where the main program waits for the asynchronous method and waits for the result of the asynchronous method.
3. Poll IAsyncResult returned by BeginInvoke, IAsyncResult.IsCompeted to determine when the asynchronous call is completed, and then call EndInvoke. This process is personally thought to be related to
The same.
4. Pass the delegate for the callback method to BeginInvoke. This method is executed on the ThreadPool thread after the asynchronous call is completed, and it can call EndInvoke. This is mandatory
Replace the callback function with IAsyncResult.AsyncState (the last parameter of BeginInvoke method) as the delegate, and then use the delegate to execute EndInvoke.
Warning always calls EndInvoke after the asynchronous call completes.
If you don't understand the above, you can understand it later.
example
1) let's start with a simple example of an asynchronous method without a callback function
Please read the comments carefully when you run the program. It is helpful to understand. Also, if you synchronize both of the commented methods, you will find the speed advantage of running asynchronously.
using System;
namespace ConsoleApplication1
{
class Class1
{
// Commissioned by the statement
public delegate void AsyncEventHandler();
// Asynchronous methods
void Event1()
{
Console.WriteLine("Event1 Start");
System.Threading.Thread.Sleep(4000);
Console.WriteLine("Event1 End");
}
// Synchronized methods
void Event2()
{
Console.WriteLine("Event2 Start");
int i=1;
while(i<1000)
{
i=i+1;
Console.WriteLine("Event2 "+i.ToString());
}
Console.WriteLine("Event2 End");
}
[STAThread]
static void Main(string[] args)
{
long start=0;
long end=0;
Class1 c = new Class1();
Console.WriteLine("ready");
start=DateTime.Now.Ticks;
// Commissioned by instance
AsyncEventHandler asy = new AsyncEventHandler(c.Event1);
// The asynchronous call starts with no callback functions and AsyncState, for null
IAsyncResult ia = asy.BeginInvoke(null, null);
// Synchronizing starts,
c.Event2();
// End asynchronously. If no end occurs, 1 Block until the call is complete, and return the function's return , if any.
asy.EndInvoke(ia);
// It's all synchronous.
//c.Event1();
//c.Event2();
end =DateTime.Now.Ticks;
Console.WriteLine(" Time scale difference ="+ Convert.ToString(end-start) );
Console.ReadLine();
}
}
}
2) let's look at the asynchronous operation of WebRequest and WebResponse with callback functions.
using System;
using System.Net;
using System.Threading;
using System.Text;
using System.IO;
// RequestState Class is used to pass
// Asynchronous calls pass data
public class RequestState
{
const int BUFFER_SIZE = 1024;
public StringBuilder RequestData;
public byte[] BufferRead;
public HttpWebRequest Request;
public Stream ResponseStream;
// Create a decoder of the appropriate encoding type
public Decoder StreamDecode = Encoding.UTF8.GetDecoder();
public RequestState()
{
BufferRead = new byte[BUFFER_SIZE];
RequestData = new StringBuilder("");
Request = null;
ResponseStream = null;
}
}
// ClientGetAsync Make an asynchronous request
class ClientGetAsync
{
public static ManualResetEvent allDone = new ManualResetEvent(false);
const int BUFFER_SIZE = 1024;
public static void Main(string[] args)
{
if (args.Length < 1)
{
showusage();
return;
}
// Get it from the command line URI
Uri HttpSite = new Uri(args[0]);
// Create the request object
HttpWebRequest wreq = (HttpWebRequest)WebRequest.Create(HttpSite);
// Creating a state object
RequestState rs = new RequestState();
// Add the request to the state so that it can be passed back and forth
rs.Request = wreq;
// Make an asynchronous request
IAsyncResult r = (IAsyncResult)wreq.BeginGetResponse(new AsyncCallback(RespCallback), rs);
// will ManualResetEvent Set to Wait .
// So that the application does not exit before calling the callback
allDone.WaitOne();
}
public static void showusage()
{
Console.WriteLine(" Try to get (GET) 1 a URL");
Console.WriteLine("\r\n Usage: :");
Console.WriteLine("ClientGetAsync URL");
Console.WriteLine(" Example: :");
Console.WriteLine("ClientGetAsync http://www.microsoft.com/net/");
}
private static void RespCallback(IAsyncResult ar)
{
// Get from asynchronous results RequestState object
RequestState rs = (RequestState)ar.AsyncState;
// from RequestState To obtain HttpWebRequest
HttpWebRequest req = rs.Request;
// call EndGetResponse generate HttpWebResponse object
// This object comes from the request made above
HttpWebResponse resp = (HttpWebResponse)req.EndGetResponse(ar);
// Now that we have the response, we should follow
// The response stream is starting to read
Stream ResponseStream = resp.GetResponseStream();
// This read operation is also done asynchronously, so we
// Will be in RequestState Storage flow
rs.ResponseStream = ResponseStream;
// Please note that, rs.BufferRead Is passed to the BeginRead .
// This is where the data will be read in.
IAsyncResult iarRead = ResponseStream.BeginRead(rs.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs);
}
private static void ReadCallBack(IAsyncResult asyncResult)
{
// from asyncresult To obtain RequestState object
RequestState rs = (RequestState)asyncResult.AsyncState;
// Take out the RespCallback Set in the ResponseStream
Stream responseStream = rs.ResponseStream;
// At this time rs.BufferRead Should have 1 Some of the data.
// The read operation will tell us if there is data there
int read = responseStream.EndRead(asyncResult);
if (read > 0)
{
// To prepare Char Array buffer, used to send Unicode conversion
Char[] charBuffer = new Char[BUFFER_SIZE];
// Converts the byte stream to Char Array, and then convert to a string
// len Shows how many characters are converted to Unicode
int len = rs.StreamDecode.GetChars(rs.BufferRead, 0, read, charBuffer, 0);
String str = new String(charBuffer, 0, len);
// Appends the most recently read data to RequestData stringbuilder Object,
// The object is contained in RequestState In the
rs.RequestData.Append(str);
// Now send another 1 Three asynchronous calls to read more data
// Note that this procedure will be called again and again until
// responseStream.EndRead return -1
IAsyncResult ar = responseStream.BeginRead(rs.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs);
}
else
{
if (rs.RequestData.Length > 1)
{
// All data has been read, so it is displayed to the console
string strContent;
strContent = rs.RequestData.ToString();
Console.WriteLine(strContent);
}
// Close the response flow
responseStream.Close();
// Set up the ManualResetEvent So that the main thread can exit
allDone.Set();
}
return;
}
}
There are callback functions and asynchronous operations in asynchronous callbacks.
First, get ResponseStream asynchronously, and then read the data asynchronously.
This is a classic program. You can learn a lot from it. Let's talk about it together.
conclusion
As mentioned above,.net framework can invoke any method asynchronously. So asynchrony is very useful.
There are also many methods for asynchronous invocation in the.net framework class library. Generally, 1 is the macro representation of asynchronous operation with the beginning of Begin and the end of End forming 1 pair, asynchronous delegate method, plus two callback functions and AsyncState parameters. So to do asynchronous programming, don't forget to delegate delegate, Begin, End, AsyncCallBack delegate, AsyncState instance (cast by IAsyncResult.AsyncState in the callback function), IAsycResult(monitor async), that's enough to understand what async is all about.