Reputation: 61
I have a method that processes thousands of items and it takes a long time.
What is the "right" way to have the method that is doing the long operation report back its progress as it does this?
For example, if I wanted to have a progress bar in my UI show the progress of some long running method in another thread.
Upvotes: 3
Views: 559
Reputation: 124696
A long-running task, whether running in a dedicated background thread or not, may want to communicate with the caller in one of two ways:
To report progress (with a BackgroundWorker this corresponds to calling BackgroundWorker.ReportProgress
)
To check if cancellation has been requested (with a BackgroundWorker this corresponds to examining the CancellationPending
property).
It's sometimes useful for a long-running process to be able to communicate with the caller in this way without knowing or caring if it is being run from a BackgroundWorker. I have therefore created an interface IProgress
which abstracts this functionality with a method ReportProgress
and a property CancellationPending
. I have an enhanced version of BackgroundWorker that implements this interface, and also alternative implementations that do not use a BackgroundWorker.
For example, a console application might run a long-running task in the foreground. Its implementation of IProgress.ReportProgress
could e.g. use Console.WriteLine
if running in verbose mode. Its implementation of IProgress.CancellationPending
could check if CTRL-C has been pressed. The same long-running task could be called from this console application and from a WinForms application that uses a BackgroundWorker.
Personally I think an abstraction like this should have been included in the .NET Framework when BackgroundWorker was designed.
Upvotes: 1
Reputation: 18815
In this particular case I would be inclined to create a custom event and fire it from the long running process, and just subscribe whatever UI elements you want updated to the event in event handlers. (UI is always updated in the main UI thread anyway)
Upvotes: 1
Reputation: 300559
Use a BackgroundWorker.
There are several SO questions on the BackgroundWorker, for example:
Upvotes: 4