Почему это происходит намного медленнее, если я использую ReadAsync/WriteAsync?C#

Место общения программистов C#
Ответить
Anonymous
 Почему это происходит намного медленнее, если я использую ReadAsync/WriteAsync?

Сообщение Anonymous »

Для архива размером 400 МБ это выполняется за несколько секунд.

Код: Выделить всё

private static async Task ExtractFilesAsync(this ZipArchive archive, string destination, IProgress progress = null)
{
await Task.Run(() =>
{
long bytesWritten = 0;
long totalBytes = archive.GetUncompressedSize();
int percent = 0;
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (!entry.IsDirectory())
{
string fullPath = Path.Combine(destination, entry.FullName);

using (FileStream writeStream = File.OpenWrite(fullPath))
{
using (Stream readStream = entry.Open())
{
int chunkSize = 1024;
byte[] buffer = new byte[chunkSize];

while (true)
{
int bytesRead = readStream.Read(buffer, 0, chunkSize);
if (bytesRead == 0)
{
break;
}
writeStream.Write(buffer, 0, bytesRead);
bytesWritten += bytesRead;
int newPercent = (int)(bytesWritten / (double)totalBytes * 100.0);
if (newPercent > percent)
{
percent = newPercent;
progress?.Report(percent);
Trace.WriteLine($"{percent}");
}
}
}
}
}
}
});
}
Но когда я использую асинхронную версию Stream.Read/Write, это занимает около минуты.

Код: Выделить всё

private static async Task ExtractFilesAsync(this ZipArchive archive, string destination, IProgress progress = null)
{
long bytesWritten = 0;
long totalBytes = archive.GetUncompressedSize();
int percent = 0;
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (!entry.IsDirectory())
{
string fullPath = Path.Combine(destination, entry.FullName);

using (FileStream writeStream = File.OpenWrite(fullPath))
{
using (Stream readStream = entry.Open())
{
int chunkSize = 1024;
byte[] buffer = new byte[chunkSize];

while (true)
{
int bytesRead = await readStream.ReadAsync(buffer, 0, chunkSize);
if (bytesRead == 0)
{
break;
}
await writeStream.WriteAsync(buffer, 0, bytesRead);
bytesWritten += bytesRead;
int newPercent = (int)(bytesWritten / (double)totalBytes * 100.0);
if (newPercent > percent)
{
percent = newPercent;
progress?.Report(percent);
Trace.WriteLine($"{percent}");
}
}
}
}
}
}

}
Почему?

Подробнее здесь: https://stackoverflow.com/questions/793 ... writeasync
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»