Я хочу загрузить большой файл с сервера с ограниченной передачей, используя несколько потоков с HttpWebRequest.AddRange(int, int)
. Проблема в том, что все мои потоки, кроме одного, блокируются на GetResponse(), возможно, потому что они хотят повторно использовать соединение первого потока. Я установил свойство KeepAlive запроса на false, и я увеличил максимальный предел одновременных соединений с ServicePointManager.DefaultConnectionLimit = 1000;
HttpWebRequest force new connection
Смешная вещь, она иногда работает. Он работает большую часть времени, если я использую 2 потока, иногда с 3, и я никогда не видел, чтобы он работал с 4 или более потоками.
Это часть моего кода, не очень важные части удалены, но этот сниппет является непрерывным блоком в моем коде, и я ничего не удалял между ними, несмотря на комментарии.
for (int i=0; i < threadpool; i++)
{
pool[i] = new Thread(new ParameterizedThreadStart((object id) =>
{
int myId = (int)(id);
Console.WriteLine("StartThread " + myId);
byte[] buffer = new byte[chunksize];
while (currentChunk < chunks)
{
int myJob = -1;
HttpWebResponse response = null;
lock (currentChunkLock)
{
myJob = currentChunk++;
}
Console.WriteLine(myId + " GOT JOB " + myJob);
HttpWebRequest request = MakeRangedRequest(url, myJob * chunksize, chunksize);
Console.WriteLine(myId + " MADE REQUEST " + myJob);
response = (HttpWebResponse)request.GetResponse();
//They get all stuck here
Console.WriteLine(myId + " GOT RESPONSE " + myJob);
int totalCount = 0;
int targetCount = (myJob + 1 == chunks) ? lastChunkSize : chunksize;
Thread.Sleep(1);
while (totalCount < targetCount)
{
//The only thread that passes is stuck here, it won't allow other threads to continue.
int left = targetCount-totalCount;
int count = response.GetResponseStream().Read(buffer, totalCount, left > 1024 ? 1024 : left);
totalCount += count;
totalBytesSoFar += count;
Console.WriteLine("READING " + myId + "/" + totalCount);
Thread.Sleep(1);
}
response.Close();
Console.WriteLine(myId + " READ BUFFER " + myJob);
lock (file)
{
file.Seek(myJob * chunksize, SeekOrigin.Begin);
file.Write(buffer, 0, chunksize);
file.Flush();
}
Console.WriteLine(myId + " WRITE FILE " + myJob);
Console.WriteLine("Current chunk: " + myJob + "/" + chunks + "\r");
Console.WriteLine("Thread " + myId);
Thread.Sleep(1);
}
Console.WriteLine("Thread " + myId + " out.");
lock (threadsDonePool)
{
threadsDone++;
if (threadsDone == threadpool)
{
file.Close();
Console.WriteLine("File Closed.");
}
}
}));
pool[i].Start(i);
}
А вот функция MakeRangedRequest:
static HttpWebRequest MakeRangedRequest(string url, int from, int size)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AddRange(from, from + size);
request.KeepAlive = false;
return request;
}
я вынужден делать все это с помощью классов TCP? Было бы замечательно придерживаться HttpWebRequest
Это ничего не меняет. Все еще застрял в этом цикле. –