我有一种通过TCP连接下载文件的方法,并且我想在控制台上显示下载完成指示器。 我当前使用的方法是引发事件以显示进度条并对其进行更新。
我的问题是显示不同步,并且极大地减缓了下载过程。我尝试使用Tasks处理事件,但无法产生良好的结果,因为多个线程会同时更新进度条,而且很混乱。
下载方法:
public void DownloadFile(Stream stream)
{
if (!stream.CanWrite)
{
// The stream can't be written : invalid argument
throw new ArgumentException();
}
// Get the data lenght first
var dataLength = long.Parse(ReadLine());
// Send ready flag
WriteLine("{OK}");
var buffer = new byte[DEFAULT_BUFFER_SIZE];
long bytesWritten = 0;
try
{
// Notify that the stream transfert started if the handler has been implemented
StreamTransfertStartEvent?.Invoke(dataLength);
int bytesRead;
while ((bytesRead = binaryReader.Read(buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, bytesRead);
bytesWritten += bytesRead;
// Notify that the stream transfert progress changed if the handler has been implemented
StreamTransfertProgressEvent?.Invoke(bytesWritten);
// The file has been totally written
if (bytesWritten == dataLength)
{
break;
}
}
}
catch (Exception)
{
StreamTransfertFailEvent?.Invoke();
throw new NetworkException();
}
}
您可以在代码中看到我用来更新进度条的3个事件:
对于进度条更新代码(仅由StreamTransfertProgressEvent处理程序调用的代码):
public static void Update(long current)
{
var newCompletion = (int)((decimal)current / total * 100);
// Transfert progressed
if (completion != newCompletion)
{
completion = newCompletion;
if (completion % 2 == 0)
{
Console.SetCursorPosition(1, lastLine - 1);
Console.Write(new string('=', completion / 2 - 1));
Console.Write('>');
}
var leftStart = 52 - total.ToString().Length - 7 - current.ToString().Length;
Console.SetCursorPosition(leftStart, lastLine);
Console.Write(current);
// Transfert finished
if (completion == 100)
{
Console.SetCursorPosition(50, lastLine - 1);
Console.Write('=');
End();
}
}
}