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
progressparameter may benullif the caller doesn’t need progress reports, so be sure to check for this in yourasyncmethod. - 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 itsProgressChangedevent in that context. So you don’t have to worry about marshaling back to the UI thread before callingReport.