I have a project to download using multithread over Http. It downloads the content partially.
For some URLs and low download speed, some of the partial download threads waits too much on while loops' without getting data and after a few times the thread directly exits without executing the code after the while loop. I don't understand how can it be.
My code:
void DownloadProcedure()
{
file = new FileStream(this.FullPath,
FileMode.Create, FileAccess.ReadWrite);
#region Request-Response
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12
| SecurityProtocolType.Ssl3;
HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
req.Accept = "*/*";
req.Timeout = 3000;
req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)";
req.AllowAutoRedirect = true;
req.MaximumAutomaticRedirections = 5;
req.ServicePoint.ConnectionLimit += 2;
req.ServicePoint.Expect100Continue = true;
req.ProtocolVersion = HttpVersion.Version10;
if (rangeAllowed)
req.AddRange(from, to);
resp = req.GetResponse() as HttpWebResponse;
#endregion
#region Some Stuff
contentLength = resp.ContentLength;
if (rangeAllowed && contentLength != to - from + 1)
throw new Exception("Incorrect response content");
tempStream = resp.GetResponseStream();
int bytesRead = 0;
byte[] buffer = new byte[4096];
stp.Start();
#endregion
#region Procedure Loop
while ((bytesRead = tempStream.Read(buffer, 0, buffer.Length)) > 0)
{
while (wait) ;
if (totalBytesRead + bytesRead > contentLength)
bytesRead = (int)(contentLength - totalBytesRead);
file.Write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
last40Speed[counter] = (int)(totalBytesRead / Math.Ceiling(stp.Elapsed.TotalSeconds));
counter = (counter >= 39) ? 0 : counter + 1;
double tempProgress = Helper.GetTwoDigits(totalBytesRead * 1d / contentLength * 100);
if (progress != tempProgress)
{
progress = tempProgress;
aop.Post(new SendOrPostCallback(delegate
{
if (DownloadPartProgressChanged != null)
DownloadPartProgressChanged(this, EventArgs.Empty);
}), null);
}
if (stop || (rangeAllowed && totalBytesRead == to - from + 1))
{
break;
}
}
#endregion
#region Close Resources
file.Close();
resp.Close();
tempStream.Close();
req.Abort();
resp.Dispose();
stp.Stop();
#endregion
Debug.WriteLine("Threads' exit");
}
In this code every download threads have to execute the Debug.WriteLine code at the last line, but some of them doesn't execute it. The output says The thread 0x... has exited with code 259 (0x103).
for each thread, but doesn't write Threads' exit
for each.
The output:
Download status
As you see, some of the download threads stops and exits directly. What is the reason of this problem?
UPDATE:
Thread creation:
public void Start()
{
Task th = new Task(() =>
{
createFirstPartitions();
});
th.Start();
}
void createFirstPartitions()
{
size = Helper.GetContentLength(url, ref rangeAllowed, ref url);
for (int i = 0; i < numberOfParts; i++)
{
PartialDownloader temp = createNewPD(i, numberOfParts, size);
temp.DownloadPartProgressChanged += temp_DownloadPartProgressChanged;
temp.DownloadPartCompleted += temp_DownloadPartCompleted;
pdlist.Add(temp);
temp.Start();
totalPartition++;
}
}
PartialDownloader createNewPD(int order, int parts, long contentLength)
{
long division = contentLength / parts;
long remaining = contentLength % parts;
long start = division * order;
long end = start + division - 1;
end += (order == parts - 1) ? remaining : 0;
return new PartialDownloader(url, tempDirectory,
Guid.NewGuid().ToString(), start, end, true);
}