这是对上篇博文提到的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的内容下载保存在文件中!