No, no, you'll upload the file all over again, even if you didn’t reload a couple of bytes. Save in the task for loading a list of underloaded areas, and load only the necessary one.
Well, it is better to use async / await (the code of a suitable producer / consumer is taken from here ).
Here is the outline of the code:
async Task SingleConsumerTask() { while (await downloadQueue.OutputAvailableAsync()) { FileItem file; if (!downloadQueue.TryReceive(out file)) continue; try { if (file.Range.End == null) { var sizeRequest = (FtpWebRequest)InitWebRequest(file.RemoteUri); sizeRequest.Method = WebRequestMethods.Ftp.GetFileSize; using (var response = (FtpWebResponse)await sizeRequest.GetResponseAsync()) file.Range.End = response.ContentLength; } var request = (FtpWebRequest)InitWebRequest(file.RemoteUri); request.Method = WebRequestMethods.Ftp.DownloadFile; request.ContentOffset = file.Range.Start; using (var response = (FtpWebResponse)await request.GetResponseAsync()) { var buf = new byte[1024 * 1024]; var s = response.GetResponseStream(); while (file.Range.Start < file.Range.End) { var actuallyRead = await s.ReadAsync(buf, 0, buf.Length); if (actuallyRead == 0) // error { file.numberOfRetries++; break; } file.Range.Start += actuallyRead; // у вас есть буфер с данными, отправьте его в очередь на запись в файл // и загружайте тем временем дальше } } } catch (WebException) { file.numberOfRetries++; } finally { if (file.Range.End == null || file.Range.Start < file.Range.End) { if (file.numberOfRetries < 10) { await downloadQueue.SendAsync(file); } else { // запостить в список зафейлившихся загрузок } } } } } private static WebRequest InitWebRequest(string uri) { var request = WebRequest.Create(uri); request.Credentials = new NetworkCredential(Settings.Login, Settings.Password); return request; }
Well, if you want to pause before reconnecting, add to FileInfo time from which you can try to load again.