在我的下载器中添加暂停和继续功能 [英] Adding pause and continue ability in my downloader
问题描述
我正在用 C# 创建一个下载器.我正在使用 WebClient 类.要在单击按钮时暂停下载,我可以想到使用 Thread.因此,当我创建线程并将其附加到我的文件下载时,如下所示
I am creating a downloader in C#. I am using WebClient class. To pause downloading on a button click I could just think of using Thread. So when I created thread and attached it with my file downloading as below
WebClient web = new WebLCient();
Thread dwnd_thread = new Thread(Program.web.DownloadFileAsync(new Uri(Program.src), Program.dest));
它给了我以下错误:'System.Threading.Thread.Thread(System.Threading.ThreadStart)'的最佳重载方法匹配有一些无效参数"和参数‘1’:无法从‘void’转换为‘System.Threading.ThreadStart’".
it is giving me following errors: "The best overloaded method match for 'System.Threading.Thread.Thread(System.Threading.ThreadStart)' has some invalid arguments" and "Argument '1': cannot convert from 'void' to 'System.Threading.ThreadStart'".
然后我想如果我暂停我的系统主线程,那么它可能会阻塞我的整个过程,因为我在下面的代码行中使用了
Then I thought if I pause my system main thread then it could block my whole process for that I used below line of code
System.Threading.Thread.Sleep(100);
但它什么也没做.有人可以告诉我暂停/下载的更好方法是什么,以及如何使用线程来暂停我的下载过程.
but it is doing nothing at all. Can somebody tell me what could be a better approach for pause/downloading and how to use thread to pause my downloading process.
推荐答案
由于没有暂停/恢复下载请求的标准方式,您必须实现自己的机制.下面是一段代码,其中包含一个示例,说明这种机制的外观.FileDownload
类有 3 个参数:
As there's no standard way of pause/resume a download request, you'll have to implement your own mechanism. Below is a block of code, containing an example of how such a mechanism could look. The class FileDownload
takes 3 parameters:
source
- 要下载的文件的 url.
source
- url to the file, to download.
destination
- 保存文件的位置.
destination
- where to save the file.
chunkSize
- 在检查是暂停还是继续下载之前要读取的字节数.
chunkSize
- how many bytes to read, before checking whether to pause or continue the download.
public class FileDownload
{
private volatile bool _allowedToRun;
private string _source;
private string _destination;
private int _chunkSize;
private Lazy<int> _contentLength;
public int BytesWritten { get; private set; }
public int ContentLength { get { return _contentLength.Value; } }
public bool Done { get { return ContentLength == BytesWritten; } }
public FileDownload(string source, string destination, int chunkSize)
{
_allowedToRun = true;
_source = source;
_destination = destination;
_chunkSize = chunkSize;
_contentLength = new Lazy<int>(() => Convert.ToInt32(GetContentLength()));
BytesWritten = 0;
}
private long GetContentLength()
{
var request = (HttpWebRequest)WebRequest.Create(_source);
request.Method = "HEAD";
using (var response = request.GetResponse())
return response.ContentLength;
}
private async Task Start(int range)
{
if (!_allowedToRun)
throw new InvalidOperationException();
var request = (HttpWebRequest)WebRequest.Create(_source);
request.Method = "GET";
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)";
request.AddRange(range);
using (var response = await request.GetResponseAsync())
{
using (var responseStream = response.GetResponseStream())
{
using (var fs = new FileStream(_destination, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
{
while (_allowedToRun)
{
var buffer = new byte[_chunkSize];
var bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead == 0) break;
await fs.WriteAsync(buffer, 0, bytesRead);
BytesWritten += bytesRead;
}
await fs.FlushAsync();
}
}
}
}
public Task Start()
{
_allowedToRun = true;
return Start(BytesWritten);
}
public void Pause()
{
_allowedToRun = false;
}
}
用法:
static void Main(string[] args)
{
var fw = new FileDownload("http://download.microsoft.com/download/E/E/2/EE2D29A1-2D5C-463C-B7F1-40E4170F5E2C/KinectSDK-v1.0-Setup.exe", @"D:KinetSDK.exe", 5120);
// Display progress...
Task.Factory.StartNew(() =>
{
while (!fw.Done)
{
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write(string.Format("ContentLength: {0} | BytesWritten: {1}", fw.ContentLength, fw.BytesWritten));
}
});
// Start the download...
fw.Start();
// Simulate pause...
Thread.Sleep(500);
fw.Pause();
Thread.Sleep(2000);
// Start the download from where we left, and when done print to console.
fw.Start().ContinueWith(t => Console.WriteLine("Done"));
Console.ReadKey();
}
这篇关于在我的下载器中添加暂停和继续功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!