把信号机隐藏起来,让调用方干净一点。
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Threading;
namespace prjDownLoad
{
class Program
{
static void Main(string[] args)
{
//实例化下载工具
DownloadUtil du = new DownloadUtil();
//订阅事件
du.ReadCompleted += new ReadCompletedHandler(du_ReadCompleted);
du.ReadProgress += new ReadProgressHandler(du_ReadProgress);
du.DownloadData();
}
static void du_ReadProgress(int x)
{
Console.WriteLine("下载了{0}字节",x);
}
static void du_ReadCompleted()
{
Console.WriteLine("下载完成了。");
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace prjDownLoad
{
//读取完成委托
public delegate void ReadCompletedHandler();
}
using System;
using System.Collections.Generic;
using System.Text;
namespace prjDownLoad
{
//读取过程委托
public delegate void ReadProgressHandler(int x);
}
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace prjDownLoad
{
/// <summary>
/// 下载信息实体类
/// </summary>
[Serializable]
public class DownloadInfo
{
Stream readSt;
/// <summary>
/// 读取数据的流
/// </summary>
public Stream ReadSt
{
get { return readSt; }
set { readSt = value; }
}
Stream writeSt;
/// <summary>
/// 写入数据的流
/// </summary>
public Stream WriteSt
{
get { return writeSt; }
set { writeSt = value; }
}
byte[] buffer = new byte[1024];
/// <summary>
/// 缓冲字节数组,用来存储从流中读取的数据的容器
/// </summary>
public byte[] Buffer
{
get { return buffer; }
set { buffer = value; }
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net;
using System.IO;
namespace prjDownLoad
{
public class DownloadUtil
{
//添加一个AutoResetEvent
//这是一个信号机
AutoResetEvent are=new AutoResetEvent(false);
//读取完成事件
public event ReadCompletedHandler ReadCompleted;
//读取过程事件
public event ReadProgressHandler ReadProgress;
public void DownloadData()
{
//不光WebResponse的获得使用异步方式
//连读取数据都使用异步方式。
//创建WebRequest对象
WebRequest wr = WebRequest.Create("http://blog.sina.com.cn/dalishuishou");
//开始异步地获取回应对象
//如果有了回应对象,那么把过程交给GetResponseCallBack去处理
wr.BeginGetResponse(new AsyncCallback(GetResponseCallBack), wr);
are.WaitOne();
}
/// <summary>
/// 当有回应对象时调用这个方法来处理。
/// </summary>
/// <param name="result"></param>
void GetResponseCallBack(IAsyncResult result)
{
//拿到那个请求对象
WebRequest wr = result.AsyncState as WebRequest;
//如果回应回完了,那么拿到回应对象
WebResponse wsp = wr.EndGetResponse(result);
//从回应中拿到流
Stream st = wsp.GetResponseStream();
//输出的文件流,此处也可替换为其他的流。
FileStream fs = new FileStream("c:\\ee.txt", FileMode.Create, FileAccess.Write);
//将异步操作过程中用到的信息封装为对象
DownloadInfo di = new DownloadInfo();
di.ReadSt = st;
di.WriteSt = fs;
//传入异步读取方法中
//第一个参数:读取的内容放到啥地方。
//第二个参数:从流的啥地方开始读取,一般从头开始,选择0。
//第三个参数:读取多少数据,一般容器多大,就读取多少数据。
//第四个参数:当读取完成后调用的方法,注意这个方法不是把所有数据都读取完成
//