在我的下载程序中添加暂停和继续function

我正在用C#创建一个下载程序。 我正在使用WebClient类。 要在按钮上暂停下载,我可以考虑使用Thread。 因此,当我创建线程并将其与我的文件下载附加如下

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)’的最佳重载方法匹配’有一些无效的参数”和“Argument’1’:无法从’void’转换为’ System.Threading.ThreadStart’”。

然后我想如果我暂停我的系统主线程然后它可以阻止我在下面的代码行使用的整个过程

 System.Threading.Thread.Sleep(100); 

但它什么都不做。 有人可以告诉我什么是更好的暂停/下载方法以及如何使用线程暂停我的下载过程。

由于暂停/恢复下载请求没有标准方法,因此您必须实现自己的机制。 下面是一段代码,包含这种机制的外观示例。 FileDownload类有3个参数:

  • source – url to the file,to download。

  • destination – 保存文件的位置。

  • chunkSize – 在检查是暂停还是继续下载之前要读取的字节数。


 public class FileDownload { private volatile bool _allowedToRun; private string _source; private string _destination; private int _chunkSize; private Lazy _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(() => 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(); } 

遗憾的是,WebClient无法暂停下载。 因此,您必须在后台线程上使用WebRequest并暂停获取带有标志的响应流。 这是示例代码。 但请确保您无法暂停,因为如果一段时间内没有任何传输,TCP连接将被关闭。 因此,如果恢复下载失败,则必须重新开始下载。

 public class DownloadJob { public delegate void DownloadCompletedDelegate(Stream stream); //completion download event public event DownloadCompletedDelegate OnDownloadCompleted; //sync object private object _lock = new object(); //pause flag private bool _bPause = false; //Pause download public void Pause() { lock (_lock) { _bPause = true; } } //Resume download public void Resume() { lock (_lock) { _bPause = false; } } //Begin download with URI public void BeginDowload(Uri uri) { //Create Background thread Thread downLoadThread = new Thread( delegate() { WebRequest pWebReq = WebRequest.Create(uri); WebResponse pWebRes = pWebReq.GetResponse(); using (MemoryStream pResultStream = new MemoryStream()) using (Stream pWebStream = pWebRes.GetResponseStream()) { byte[] buffer = new byte[256]; int readCount = 1; while (readCount > 0) { //Read download stream readCount = pWebStream.Read(buffer, 0, buffer.Length); //Write to result MemoryStream pResultStream.Write(buffer, 0, readCount); //Waiting 100msec while _bPause is true while (true) { lock (_lock) { if (_bPause == true) { Thread.Sleep(100); } else { break; } } } pResultStream.Flush(); } //Fire Completion event if (OnDownloadCompleted != null) { OnDownloadCompleted(pResultStream); } } } ); //Start background thread job downLoadThread.Start(); } }