Fixed Read not blocking

This commit is contained in:
Michael Bucari-Tovo 2021-07-03 14:31:02 -06:00
parent da68ddc9b8
commit 9cde6bddbd

View File

@ -79,7 +79,8 @@ namespace AaxDecrypter
private Stream _networkStream { get; set; } private Stream _networkStream { get; set; }
private bool hasBegunDownloading { get; set; } private bool hasBegunDownloading { get; set; }
private bool isCancelled { get; set; } private bool isCancelled { get; set; }
private Action cancelDownloadCallback { get; set; } private bool finishedDownloading { get; set; }
private Action downloadThreadCompleteCallback { get; set; }
#endregion #endregion
@ -154,7 +155,11 @@ namespace AaxDecrypter
public async Task BeginDownloading() public async Task BeginDownloading()
{ {
if (ContentLength != 0 && WritePosition == ContentLength) if (ContentLength != 0 && WritePosition == ContentLength)
{
hasBegunDownloading = true;
finishedDownloading = true;
return; return;
}
if (ContentLength != 0 && WritePosition > ContentLength) if (ContentLength != 0 && WritePosition > ContentLength)
throw new Exception($"Specified write position (0x{WritePosition:X10}) is larger than the file size."); throw new Exception($"Specified write position (0x{WritePosition:X10}) is larger than the file size.");
@ -178,11 +183,6 @@ namespace AaxDecrypter
Thread downloadThread = new Thread(() => DownloadFile()); Thread downloadThread = new Thread(() => DownloadFile());
downloadThread.Start(); downloadThread.Start();
while(!File.Exists(SaveFilePath) && new FileInfo(SaveFilePath).Length > 1000)
{
Thread.Sleep(100);
}
hasBegunDownloading = true; hasBegunDownloading = true;
return; return;
} }
@ -208,7 +208,6 @@ namespace AaxDecrypter
_writeFile.Flush(); _writeFile.Flush();
WritePosition = downloadPosition; WritePosition = downloadPosition;
Update(); Update();
nextFlush = downloadPosition + DATA_FLUSH_SZ; nextFlush = downloadPosition + DATA_FLUSH_SZ;
} }
@ -225,7 +224,8 @@ namespace AaxDecrypter
if (WritePosition > ContentLength) if (WritePosition > ContentLength)
throw new Exception("Downloaded file is larger than expected."); throw new Exception("Downloaded file is larger than expected.");
cancelDownloadCallback?.Invoke(); finishedDownloading = true;
downloadThreadCompleteCallback?.Invoke();
} }
#endregion #endregion
@ -362,21 +362,17 @@ namespace AaxDecrypter
if (!hasBegunDownloading) if (!hasBegunDownloading)
throw new Exception($"Must call {nameof(BeginDownloading)} before attempting to read {nameof(NetworkFileStream)};"); throw new Exception($"Must call {nameof(BeginDownloading)} before attempting to read {nameof(NetworkFileStream)};");
long toRead = Math.Min(count, Length - Position);
long requiredPosition = Position + toRead;
//read operation will block until file contains enough data //read operation will block until file contains enough data
//to fulfil the request. //to fulfil the request.
while (requiredPosition > WritePosition)
Thread.Sleep(0);
return _readFile.Read(buffer, offset, count); return _readFile.Read(buffer, offset, count);
} }
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (!hasBegunDownloading)
throw new Exception($"Must call {nameof(BeginDownloading)} before attempting to read {nameof(NetworkFileStream)};");
//read operation will block until file contains enough data
//to fulfil the request.
return await _readFile.ReadAsync(buffer, offset, count, cancellationToken);
}
public override long Seek(long offset, SeekOrigin origin) public override long Seek(long offset, SeekOrigin origin)
{ {
long newPosition; long newPosition;
@ -393,7 +389,6 @@ namespace AaxDecrypter
newPosition = offset; newPosition = offset;
break; break;
} }
ReadToPosition(newPosition); ReadToPosition(newPosition);
_readFile.Position = newPosition; _readFile.Position = newPosition;
@ -406,24 +401,28 @@ namespace AaxDecrypter
/// <param name="neededPosition">The minimum required data length in <see cref="SaveFilePath"/>.</param> /// <param name="neededPosition">The minimum required data length in <see cref="SaveFilePath"/>.</param>
private void ReadToPosition(long neededPosition) private void ReadToPosition(long neededPosition)
{ {
long totalBytesRead = _readFile.Position;
byte[] buff = new byte[DOWNLOAD_BUFF_SZ]; byte[] buff = new byte[DOWNLOAD_BUFF_SZ];
do do
{ {
totalBytesRead += Read(buff, 0, DOWNLOAD_BUFF_SZ); Read(buff, 0, DOWNLOAD_BUFF_SZ);
} while (totalBytesRead < neededPosition); } while (neededPosition > WritePosition);
} }
public override void Close() public override void Close()
{ {
isCancelled = true; isCancelled = true;
cancelDownloadCallback = () => downloadThreadCompleteCallback = CloseAction;
//ensure that close will run even if called after callback was fired.
if (finishedDownloading)
CloseAction();
}
private void CloseAction()
{ {
_readFile.Close(); _readFile.Close();
_writeFile.Close(); _writeFile.Close();
_networkStream?.Close(); _networkStream?.Close();
Update(); Update();
};
} }
#endregion #endregion