У меня есть метод загрузки 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();
}
});
}
}