2

Я хочу загрузить большой файл с сервера с ограниченной передачей, используя несколько потоков с 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

ответ

0

Вы когда-нибудь пробовали делать это асинхронно?

Пожалуйста, обратитесь к этому: How to use HttpWebRequest (.NET) asynchronously?

Надеется, что это помогает

+0

Это ничего не меняет. Все еще застрял в этом цикле. –