-
-
Notifications
You must be signed in to change notification settings - Fork 63
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
)
- 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
- 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
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.
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.