2016-11-21 1 views
-2

HTTP를 통해 멀티 스레드를 사용하여 다운로드 할 프로젝트가 있습니다. 내용을 부분적으로 다운로드합니다.HTTP를 통한 스레드 다운로드는 바이트 읽기 루프에서 직접 종료됩니다.

일부 URL과 다운로드 속도가 느린 경우 일부 다운로드 스레드는 while 루프에서 데이터를 가져 오지 않고 너무 많은 시간 동안 대기하고 몇 번 지나면 스레드가 while 루프 이후 코드를 실행하지 않고 직접 종료됩니다. 나는 그것이 어떻게 될 수 있는지 이해하지 못한다.

내 코드 : 모든 다운로드 스레드가 마지막 줄에서의 Debug.WriteLine 코드를 실행해야이 코드에서

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"); 
} 

하지만, 그들 중 일부는 그것을 실행하지 않습니다. 각 스레드에 대해 The thread 0x... has exited with code 259 (0x103). 출력이 표시되지만 각각에 대해 Threads' exit을 쓰지는 않습니다.

출력 : 보시다시피, 다운로드 스레드의 일부가 정지 직접 종료

enter image description here

enter image description here

다운로드 상태를 표시합니다. 이 문제의 이유는 무엇입니까?

UPDATE :

스레드 생성 : 내 질문에 대한 간단한 답을 발견

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); 
    } 
+0

귀하의 스레드 (즉, 아마도 예외로 인해 오류있다) 0이 아닌 종료 코드로 종료된다. 출력 창에서 무엇을 말합니까? – Cameron

+0

이들은 코드로 작성된 다운로드 스레드입니다. 처음 7 개의 스레드는 성공적이고 다른 스레드는 성공하지 못합니다. 또한 출력은 '프로그램 '[3988] MultiThreadingDownloder.vshost.exe : 프로그램 추적'이 코드 0 (0x0)으로 종료되었습니다. ' '프로그램 '[3988] MultiThreadingDownloder.vshost.exe'가 코드 0으로 종료되었습니다. (0x0) .' –

+0

또한, 우리는 스레딩 부분을 우리에게 보여주지 않았습니다 ... 'from'과'to'는 어디에서 왔습니까? 그리고 기다려? – Cameron

답변

0

. 해결책은 HttpWebRequest.ReadWriteTimeout입니다. 기본값은 5 분입니다. 수용 가능한 시간으로 설정하는 것이 좋은 해결책입니다.

요청을 보내는 중에 req.ReadWriteTimeout = 5000을 추가하십시오.

는이에 코드 부분을 변경

 try 
     { 
      while ((bytesRead = tempStream.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       //.... 
       file.Write(buffer, 0, bytesRead); 
       totalBytesRead += bytesRead; 
      } 
     } 
     catch 
     { 
      //Refresh the connection 
     }