Im working on a reporting system, a series of DocumentPage
are to be created through a DocumentPaginator
. These documents include a number of WPF components that are to be instantiated so the paginator includes the correct things when later sent to the XpsDocumentWriter
(which in turn is sent to the actual printer).
My problem now is that the DocumentPage
instances take quite a while to create (enough for Windows to mark the application as frozen) so I tried to create them in a background thread, which is problematic since WPF expects the attributes on them to be set from the GUI thread. I would also like to have a progress bar showing up, indicating how many pages have been created so far. Thus, it looks like Im trying to get two things to happen in parallell on the GUI.
The problem is hard to explain and Im really not sure how to tackle it. In short:
- Create a series of
DocumentPag
e's.- These include WPF components
- These are to be created on a background thread, or use some other trick so the application isnt frozen.
- After each page is created, a WPF ProgressBar should be updated.
If there is no decent way to do this, alternate solutions and approaches are more than welcome.
A little late to the game on this one, but I just worked out a solution to this so I thought I would share. In order to display the UI elements they have to be created on the UI thread on which they will be displayed. Since the long running task is on the UI thread, it will prevent a progress bar from updating. To get around this, I created the progress bar on a new UI thread and created the pages on the main UI thread.
'ProgressDialog' was my own WPF window for displaying progress information.
'context' holds the progress data for my progress dialog. It includes a cancelled property so that I can abort the action running on the main thread. It also includes a complete property so the progress dialog can close when the Action has finished.
'Action' is the method used to create all the UI elements. It monitors the context for the cancel flag and stops generating the UI elements if the flag is set. It sets the complete flag when it is done.
I don't remember the exact reason I had to set Thread 't' to an STA thread and IsBackground to true, but I am pretty sure it won't work without them.