Using TPL when unpacking files

I've been working on an implementation of my own collection of Astron libraries from scratch, and I wanted to check my TPL usage because I'm unfamiliar with this technology: /

My app is currently unpacking .d2p files, a custom file format from a French game called Dofus. It is simply an archive of other inflated archives of another custom .dlm file format. Here is the latest issue of my app:

application edition
The progress bars came from here.

So everything seems to work as expected, files are processed at the same time, 308 million DLL files are analyzed in 10 seconds. That's exactly what I want, but I may have abused the TPL. The full project can be found at this address, but the part of the code that I want to check comes from src / Astron.Unpacker / Managers / D2PManager.cs :

public class D2PManager: BaseFileManager
{
private read-only ILogger _logger;
private read-only string _dlmFilesFolder;
public D2PManager (IContainer container): base (container)
{
_logger = ServiceLocator.Logger;
_dlmFilesFolder = container.GetInstance() .DlmOutputFolder;
}

public async Task UnpackAll (string[] file spath)
{
_logger.Log(LogLevel.Info, $ "attempt to unpack {filesPath.Length} d2p files ...");

var tasks = new list(FilesPath.Length);
tasks.AddRange (filesPath.Select (d2PFilePath => UnpackD2PFile (d2PFilePath)));

wait Task.WhenAll (tasks) .ConfigureAwait (false);
}

public async Task UnpackD2PFile (string path)
{
var d2PFile = new FileAccessor (path);
var metaUnpacker = new D2PFileMetadataUnpacker (_binaryFactory, _serDes);
metaUnpacker.Unpack (d2PFile);

var archiveUnpacker = new DlmArchivesUnpacker (_binaryFactory, _serDes, metaUnpacker.Value);
archiveUnpacker.Unpack (d2PFile);

var progressCount = 1;
var progressBar = new ProgressBar (PbStyle.SingleLine, archiveUnpacker.Values.Count);
progressBar.Refresh (0, Path.GetFileName (d2PFile.FullPath));
wait for Task.Delay (10); // does not print like this
foreach (var archive in archiveUnpacker.Values)
{
var filePath = (_dlmFilesFolder + archive.RelativePath) .Replace (& # 39; / & # 39 ;, & # 39; \ & # 39;);
var fileDirectory = Path.GetDirectoryName (filePath);
using var decompressedData = new MemoryStream ();
with var deflatedStream = new DeflateStream (new MemoryStream (archive.CompressedData),
CompressionMode.Decompress);

wait for deflatedStream.CopyToAsync (decompressedData);
if (! Directory.Exists (fileDirectory)) Directory.CreateDirectory (fileDirectory);

File.WriteAllBytes (filePath, decompressedData.GetBuffer ());
progressBar.Refresh (progressCount, filePath);
progressCount ++;
}
}
}

Here are my questions:

  • If I do not add that Task.Delay () Immediately after initializing the process bar, the files appear to be processed synchronously (the progress bar is displayed when the last operation is completed). Why is this happening?
  • Is it correct to use .ConfigureAwait (false) on Task.WhenAll () ?
  • Do I start all tasks correctly? Should not use Task.Run () instead with Task.WaitAll () ?