Пока l oop не выходит при вызове break в условии - PullRequest
0 голосов
/ 17 февраля 2020

У меня есть метод загрузки asyn c для загрузки и записи байтов. Я хочу сломать while l oop, которое читает и записывает поток, когда пользователь вызывает функцию Stop(). Но он не выходит несмотря на вызов break в условии if. Когда я отслеживаю свойство Status после вызова Stop(), оно все равно равно Downloading. Почему это происходит?

ОБНОВЛЕНИЕ: Я пробовал ключевое слово volatile для переменной stopEmergent, но оно тоже не сработало.

Метод загрузки:

class MultiThreadDownloader 
{
 ...

 public void StopAllDownloaders() 
 {
   foreach(var item in partialDownloaders) 
   {
    item.StopEmergent();
   }
  }

  ...
}

class PartialDownloader 
{
 volatile bool stopEmergent;

 public void StopEmergent() 
 {
  stopEmergent = true;
 }

 public void StartDownloadAsync() 
 {
  Task.Run(() => 
  {
   HttpWebRequest request = null;
   try 
   {
    Status = State.SendRequest;

    request = RequestCreator.CreateRequestWithHeaders(Url, headers);
    request.Timeout = 3000;
    request.ReadWriteTimeout = 3000;
    if (StartOffset >= 0 && EndOffset > 0)
     request.AddRange(StartOffset, EndOffset);
    Status = State.GetResponse;


    using(var response = (HttpWebResponse) request.GetResponse()) 
    {
     using(var fileStream = new FileStream(FilePath, FileMode.OpenOrCreate)) 
     {
      if (StartOffset >= 0 && EndOffset > 0 && EndOffset - StartOffset + 1 != response.ContentLength)
       throw new Exception("Content size is not equal content size of the range set before!");
      Status = State.GetResponseStream;


      using(var str = response.GetResponseStream()) 
      {
       var buffer = new byte[2048];
       int bytesRead;

       while ((bytesRead = str.Read(buffer, 0, buffer.Length)) > 0) 
       {
        if (stopEmergent) 
        {
         break;
        }
        if (Status != State.Downloading) 
        {
         Status = State.Downloading;
        }
        fileStream.Write(buffer, 0, bytesRead);
        fileStream.Flush();

        TotalBytesReceived += bytesRead;

        if (ProgressChanged != null)
         ProgressChanged.Invoke(this, EventArgs.Empty);

       }
       //
      }
     }
    }
    if (RemainingRange.Length > 0 && DownloadStopped != null) 
    {
     Status = State.Stopped;
     DownloadStopped(this, EventArgs.Empty);
    } else if (RemainingRange.Length == 0 && DownloadCompleted != null) 
    {
     Status = State.Completed;
     DownloadCompleted(this, EventArgs.Empty);
    } else if (RemainingRange.Length < 0) 
    {
     throw new Exception("Remaining range length is greater than 0");
    } else {}
   } catch (Exception ex) 
   {
    Status = State.Failed;
    if (DownloadFailed != null)
     DownloadFailed(this, EventArgs.Empty);
   } finally 
   {
    if (request != null)
     request.Abort();
   }
  });
 }

}
...