如果您使用System.Net.WebClient.DownloadFile()
orSystem.Net.WebClient.DownloadFileAsync()
方法,则无法暂停下载。这些方法之间的区别在于后一种方法将启动异步下载,因此如果您使用此方法,则无需自己创建单独的线程。不幸的是,使用任何一种方法执行的下载都无法暂停或恢复。
你需要使用System.Net.HttpWebRequest
. 尝试这样的事情:
class Downloader
{
private const int chunkSize = 1024;
private bool doDownload = true;
private string url;
private string filename;
private Thread downloadThread;
public long FileSize
{
get;
private set;
}
public long Progress
{
get;
private set;
}
public Downloader(string Url, string Filename)
{
this.url = Url;
this.filename = Filename;
}
public void StartDownload()
{
Progress = 0;
FileSize = 0;
commenceDownload();
}
public void PauseDownload()
{
doDownload = false;
downloadThread.Join();
}
public void ResumeDownload()
{
doDownload = true;
commenceDownload();
}
private void commenceDownload()
{
downloadThread = new Thread(downloadWorker);
downloadThread.Start();
}
public void downloadWorker()
{
// Creates an HttpWebRequest with the specified URL.
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
FileMode filemode;
// For download resume
if (Progress == 0)
{
filemode = FileMode.CreateNew;
}
else
{
filemode = FileMode.Append;
myHttpWebRequest.AddRange(Progress);
}
// Set up a filestream to write the file
// Sends the HttpWebRequest and waits for the response.
using (FileStream fs = new FileStream(filename, filemode))
using (HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse())
{
// Gets the stream associated with the response.
Stream receiveStream = myHttpWebResponse.GetResponseStream();
FileSize = myHttpWebResponse.ContentLength;
byte[] read = new byte[chunkSize];
int count;
while ((count = receiveStream.Read(read, 0, chunkSize)) > 0 && doDownload)
{
fs.Write(read, 0, count);
count = receiveStream.Read(read, 0, chunkSize);
Progress += count;
}
}
}
}
我使用了 MSDN 上HttpWebRequest.GetResponse页面中的一些代码。
除了在暂停时停止线程并在恢复时启动新线程,您还可以将while
循环更改为等到下载恢复,如下所示:
while ((count = receiveStream.Read(read, 0, chunkSize)) > 0)
{
fs.Write(read, 0, count);
count = receiveStream.Read(read, 0, chunkSize);
Progress += count;
while(!doDownload)
System.Threading.Thread.Sleep(100);
}
好处是您可以重复使用相同的线程。不利的一面是连接可能会超时并关闭。在后一种情况下,您需要检测到这一点并重新连接。
您可能还想为下载完成添加一个事件。