Skip to content

Progress feedback

Zeugma440 edited this page Aug 4, 2023 · 2 revisions

How to get progress feedback ?

Since v4.11, there are two possible ways to get progress feedback

Type Methods Feedback
Direct call Track.Save, Track.Remove Action<float> run on the calling thread
Asynchronous call await Track.SaveAsync, await Track.RemoveAsync IProgress<float> run on the ThreadPool

NB : The float stands for the % of progress, from 0% (0.0) to 100% (1.0)

Which one should I use ?

Recommendations

  • If you're making a console app, use direct calls, as benefits from using async calls are very limited when you have no UI
  • If you're making an app with an UI (e.g. Windows Forms) :
    • Use asynchronous calls if showing the individual progress inside each edited file is relevant to your users (typically, when editing one or a few files at a time)
    • Use direct calls from a background thread*if your app is designed to manage mass-tagging operations, where progress is measured by the number of processed files
    • Use direct calls from a background thread* if you need to process your files as fast as possible

* e.g. by using a BackgroundWorker

Additional observations

  • My own benchmarks clearly show that asynchronous calls are slower than direct calls by a factor of 2.5x to 14x
  • For direct calls, keep in mind that any instruction you write inside the Action<float> handler will slow down the operation, as it will be run by the very same thread that does the I/O

Why is there no async variant for reading methods ?

Contrary to writing operations that may involve moving a lot of bytes inside the source file, reading operations in ATL are generally fast.

From an architectural point of view, implementing an async variant of a given method involves duplicating and refactoring code, introducing complexity (best case) and creating duplicate chunks of code (worst case). I won't go that way if there's no obvious tradeoff.

In the source code, I can only see async writing methods. Where are the sync ones ?

Since ATL v5, sync variants are automatically generated at build-time by the excellent https://github.com/zompinc/sync-method-generator library, which allows me to focus on maintaining and testing the async variant only, preventing duplicated code from sprawling over the library as it was the case on previous versions.