I'm completely new to C# 5's new async
/await
keywords and I'm interested in the best way to implement a progress event.
Now I'd prefer it if a Progress
event was on the Task<>
itself. I know I could just put the event in the class that contains the asynchronous method and pass some sort of state object in the event handler, but to me that seems like more of a workaround than a solution. I might also want different tasks to fire off event handlers in different objects, which sounds messy this way.
Is there a way I could do something similar to the following?:
var task = scanner.PerformScanAsync();
task.ProgressUpdate += scanner_ProgressUpdate;
return await task;
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:
progress
parameter may be null
if the caller doesn't need progress reports, so be sure to check for this in your async
method.Progress
.Progress<T>
type will capture the current context (e.g., UI context) on construction and will raise its ProgressChanged
event in that context. So you don't have to worry about marshaling back to the UI thread before calling Report
.Simply put, Task
doesn't support progress. However, there's already a conventional way of doing this, using the IProgress<T>
interface. The Task-based Asynchronous Pattern basically suggests overloading your async methods (where it makes sense) to allow clients to pass in an IProgress<T>
implementation. Your async method would then report progress via that.
The Windows Runtime (WinRT) API does have progress indicators built-in, in the IAsyncOperationWithProgress<TResult, TProgress>
and IAsyncActionWithProgress<TProgress>
types... so if you're actually writing for WinRT, those are worth looking into - but read the comments below as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With