In C #, the core class WebClient can be used to easily create a download tool. But here we want to emphasize that we use asynchronous operations. The so-called Asynchronization is relative to the concept of synchronization. For example, Ajax in the Web is based on Asynchronization. It provides a good user experience, so that users do not feel the "card" (do not block the UI thread) during operations ), you can perform other operations at the same time and switch to the task interface at will. When downloading an object, if the object is too large, we can use the synchronous Download Method to download the object. In fact, the program runs continuously in the background, but we cannot see the download process. Therefore, the asynchronous method can effectively solve this problem.
Let's take a look at the program interface:
The above operations are simple, and only a few lines of code are required.
Private void button#click (object sender, EventArgs e) {using (WebClient client = new WebClient () {client. downloadFileAsync (new Uri (this. textBox1.Text. trim (), Path. getFileName (this. textBox1.Text. trim (); client. downloadProgressChanged + = client_DownloadProgressChanged; client. downloadFileCompleted + = client_DownloadFileCompleted;} void client_DownloadProgressChanged (object sender, DownloadProgressChangedEventArgs e) {this. label1.Text = string. format ("currently received {0} bytes, total file size {1} bytes", e. bytesReceived, e. totalBytesToReceive); this. progressBar1.Value = e. progressPercentage;} void client_DownloadFileCompleted (object sender, System. componentModel. asyncCompletedEventArgs e) {if (e. cancelled) {MessageBox. show ("File Download canceled", "prompt", MessageBoxButtons. OKCancel);} this. progressBar1.Value = 0; MessageBox. show ("file downloaded successfully", "prompt ");}
We only need to fill in the file address in textbox, such as thunder's: Lightning.
In C #, you can also use HttpWebRequest to asynchronously download files. The following code may be a little complicated, but it can help us understand the process of "Asynchronous" operations in depth.
First, we define a class to save the operation status:
/// <Summary> /// Request status /// </summary> public class RequestState {// <summary> /// buffer size /// </summary> public int BUFFER_SIZE {get; set ;}//< summary> /// buffer //</summary> public byte [] BufferRead {get; set ;} /// <summary> /// save path /// </summary> public string SavePath {get; set ;} /// <summary> /// Request stream // </summary> public HttpWebRequest Request {get; set ;} /// <summary> /// Response stream /// </summary> public HttpWebResponse Response {get; set ;} /// <summary> /// Stream object /// </summary> public Stream ResponseStream {get; set ;} /// <summary> /// file stream /// </summary> public FileStream {get; set ;}}
In the Click Event of a Button, type the following code:
// Download the object url string url = this. textBox1.Text. trim (); // create an initialization request object HttpWebRequest request = (HttpWebRequest) WebRequest. create (new Uri (url); // sets the download parameter RequestState requestState = new RequestState (); requestState. BUFFER_SIZE = 1024; requestState. bufferRead = new byte [requestState. BUFFER_SIZE]; requestState. request = request; requestState. savePath = Path. combine ("D :\\", Path. getFileName (url); requestState. fileStream = new FileStream (requestState. savePath, FileMode. openOrCreate); // starts asynchronous request for resources. beginGetResponse (new AsyncCallback (ResponseCallback), requestState );
We can see that asynchronous operation methods generally start with BeginGetResponse. We usually use GetResponse for many Synchronization Methods. In addition, AsyncCallback is a delegate. As mentioned above, the parameters in AsyncCallback are a method. we name it ResponseCallback and pass requestState as a parameter.
Next, let's take a look at the ResponseCallback method:
/// <Summary> /// callback function for the resource request method /// </summary> /// <param name = "asyncResult"> used to pass operations in the callback function status </param> private void ResponseCallback (IAsyncResult asyncResult) {RequestState requestState = (RequestState) asyncResult. asyncState; requestState. response = (HttpWebResponse) requestState. request. endGetResponse (asyncResult); Stream responseStream = requestState. response. getResponseStream (); requestState. responseStream = responseStream; // starts asynchronous stream reading. beginRead (requestState. bufferRead, 0, requestState. bufferRead. length, ReadCallback, requestState );}
We can see that there is another Asynchronous Operation in the callback function. Its task is to asynchronously read the response stream into the buffer.
Next, let's take a look at the ReadCallback callback function.
/// <Summary> // callback function for asynchronous stream reading /// </summary> /// <param name = "asyncResult"> used to pass operations in the callback function status </param> private void ReadCallback (IAsyncResult asyncResult) {RequestState requestState = (RequestState) asyncResult. asyncState; int read = requestState. responseStream. endRead (asyncResult); if (read> 0) {// write the data in the buffer to the file stream requestState. fileStream. write (requestState. bufferRead, 0, read); // starts to asynchronously read the stream requestState. responseStream. beginRead (requestState. bufferRead, 0, requestState. bufferRead. length, ReadCallback, requestState);} else {requestState. response. close (); requestState. fileStream. close ();}}
This is the process of writing a stream into a file, and recursively writing a file stream using the BeginRead method until the file is fully written (completely downloaded to the local ).
I have referred to the code above the official website and can query: BeginGetResponse here. This is an example of a classic asynchronous operation.