这是对上篇博文提到的IAsyncResult异步调用模式的一个实例应用,所用到的知识有:
- 通过异步回调函数实现异步操作
- 通过类实现给异步回调函数传递附加信息
- 在子线程中通过异步回调的方式通知主线程执行结果
- WebRequest和WebResponse的操作
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.IO; using System.Windows.Forms; namespace DownLoadPageFromWeb { class Program { /// <summary> /// 异步回调函数 /// </summary> /// <param name="ar"></param> static void DownloadFinished(IAsyncResult ar) { try { //传入回调函数的附加信息可以通过IAsyncResult.AsyncState接收 DownLoadTask task = ar.AsyncState as DownLoadTask; WebResponse response = task.WebRequestObject.EndGetResponse(ar); string FileContent=""; //从internet返回需要的输入流 using(StreamReader reader=new StreamReader(response.GetResponseStream(),Encoding.GetEncoding("gb2312"))) { FileContent = reader.ReadToEnd(); } //写入文件 using (StreamWriter writer = new StreamWriter(new FileStream(task.SaveToFileName, FileMode.Create), Encoding.GetEncoding("gb2312"))) { writer.Write(FileContent); } MessageBox.Show(string.Format("“{0}”下载完成!", task.SaveToFileName)); } catch (Exception ex) { MessageBox.Show(ex.Message); } } static void Main(string[] args) { string UserInputUrl = ""; string FileName = ""; Console.WriteLine("输入URL启动一个异步下载Web文件任务,输入quit退出。"); do { Console.Write("\n输入Web文件的URL:"); UserInputUrl = Console.ReadLine(); if (string.IsNullOrEmpty(UserInputUrl)) { Console.WriteLine("不能输入一个空的URL字串"); continue; } if (UserInputUrl.ToLower() == "quit") break; Console.Write("输入要保存的文件名:"); FileName = Console.ReadLine(); if (string.IsNullOrEmpty(FileName)) { Console.WriteLine("不能输入一个空的URL字串"); continue; } if (FileName.ToLower() == "quit") break; if (UserInputUrl.ToLower() == "quit") break; try { Uri webFileUri = new Uri(UserInputUrl); WebRequest webRequest = WebRequest.Create(webFileUri); //DownLoadTask用于向回调函数传递附加信息 DownLoadTask task = new DownLoadTask { SaveToFileName = FileName, WebRequestObject = webRequest }; Console.WriteLine("已在后台启动下载{0}", FileName); //BeginGetResponse 方法开始对 Internet 资源响应的异步请求。异步回调方法使用 EndGetResponse 方法返回实际的 WebResponse。第一个参数是AsyncCallback 委托(回调函数),第二个参数是附加信息 webRequest.BeginGetResponse(DownloadFinished, task); } catch (Exception ex) { Console.WriteLine(ex.Message); } } while (true); Console.WriteLine("\n敲任意键结束本示例程序..."); Console.ReadKey(); } } }
输入一个URI,再输入一个文件,将指定的URI的内容下载保存在文件中!