Всем привет. Пытаюсь разобраться с асинхронными методами на C#. Есть следующая простая задача:
Скопировать 2 файла из одного Windows-пк на другой (оба в одной локальной сети). В реальности файлов может быть ~1000, но для упрощения уменьшил до двух.
Код
using System.Diagnostics;
public static class Program
{
public static async Task Main()
{
var destinationPath = @"path\to\destination\folder";
List<string> filePaths = new()
{
@"\\remote-pc\c$\files\file1",
@"\\remote-pc\c$\files\file2",
};
var watch = Stopwatch.StartNew();
List<Task> tasks = new List<Task>();
foreach (string path in filePaths)
{
Console.WriteLine($"Start copy {Path.GetFileName(path)}");
using var sourceStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true);
using var destinationStream = new FileStream(Path.Combine(destinationPath, Path.GetFileName(path)), FileMode.CreateNew, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true);
var task = sourceStream.CopyToAsync(destinationStream).ContinueWith(_ => {
Console.WriteLine($"End copy {Path.GetFileName(path)}");
});
tasks.Add(task);
}
await Task.WhenAll(tasks);
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
Console.WriteLine(elapsedMs);
}
}
Если я правильно понимаю, async/await необходимо использовать в I/O-bound операциях - как раз этот случай (или ошибаюсь?). При выполнении строки
sourceStream.CopyToAsync(destinationStream)
вызывающий поток будет освобожден для выполнения следующей операции (видимо, это правда, так при запуске одновременно
появяются два WriteLine'a о начале копирования файлов).
Однако, анализируя время выполнения кода (elapsedMs), которое равно ~30 с. для двух файлов, делалю вывод, что файлы копируются вовсе не параллельно. При запуске копирования каждого файла отдельно, время выполнения ~20 с. и ~6 c. для каждого файла соответственно. Cледовательно при "паралелльном копировании" ожидаю общее время выполнения = времени копирования самого большого файла.
Прошу помочь разобраться в моих рассуждениях.