The recommended approach is described in the Task-based Asynchronous Pattern documentation, which gives each asynchronous method its own IProgress<T>
:
public async Task PerformScanAsync(IProgress<MyScanProgress> progress)
{
...
if (progress != null)
progress.Report(new MyScanProgress(...));
}
Usage:
var progress = new Progress<MyScanProgress>();
progress.ProgressChanged += ...
PerformScanAsync(progress);
Notes:
- By convention, the
progress
parameter may benull
if the caller doesn’t need progress reports, so be sure to check for this in yourasync
method. - Progress reporting is itself asynchronous, so you should create a new instance of your arguments each time you call (even better, just use immutable types for your event args). You should not mutate and then re-use the same arguments object for multiple calls to
Progress
. - The
Progress<T>
type will capture the current context (e.g., UI context) on construction and will raise itsProgressChanged
event in that context. So you don’t have to worry about marshaling back to the UI thread before callingReport
.