Code: Select all
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}");
}
}
}
}
}
}
});
}
Code: Select all
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}");
}
}
}
}
}
}
}
Bearbeiten:
ChunkSize wurde auf 1 MB erhöht.
Es sieht so aus, als ob Stream.ReadAsync nur etwa 15 kB pro Lesevorgang liest, während Stream.Read die gesamten MB liest. Daher ist Stream.ReadAsync der Engpass. Aber warum?