I'm trying to provide a live preview of XPS documents without hanging my UI thread. Opening the document is fast enough, but when I call GetFixedDocumentSequence(), my UI becomes unresponsive for several seconds while the document chugs away.
// creating the doc is fine (0.005 seconds)
XpsDocument doc=new XpsDocument("BigFile.xps",FileAccess.Read);
// this hangs the UI for several seconds
FixedDocumentSequence seq=XpsDocument.GetFixedDocumentSequence();
// Once I have the sequence, GetPageAsync lets me pull out pages without breaking the UI
// ....
The obvious solution is to open the document on a worker thread, but the FixedDocumentSequence is tied to the thread that created it, so I can't access it from the UI thread, and if I try to call GetPageAsync from the worker thread I get an exception because DocumentPages contain visuals.
The only thing I can think of is to create the document on a seperate UI thread, break the document into pages, and then save those pages as XPS files that the UI thread opens. But that seems like a horribly complex solution. Does anyone know if there is an alternative way to getting the DocumentPages that does not rely on the FixedDocumentSequence?
There is a simple solution. It's called multi-threaded UI and it helps you to do everything as you would do, but have two UI threads instead of one. It means that your XPS can load on a seperate UI thread without any problem. I've implemented it myself in the past, and it's good.
http://blogs.msdn.com/b/dwayneneed/archive/2007/04/26/multithreaded-ui-hostvisual.aspx
Related
I am having a bit of a problem with a WPF application. The application loads from a database and then creates a bunch of own made Usercontrols. When I load lets say 1000 of these Usercontrols the UI thread blocks. Now I have tried multiple things with loading the Usercontrols on a different thread and then adding them to the main thread, but that is simply not possible I found out (or somebody must have a proper working example).
Is it possible to create a thread with a loading animation that is not blocking while the main UI thread is doing things?
Perform most of work in the thread that loads data from database and use Dispatcher class
http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.aspx
to perform the UI related operations on the main thread.
I have a WPF application in which I'm using SoundPlayer to play several short sounds such as keyboard clicks. Sometimes, seemingly at random, the sounds will stop playing. When I navigate away from the page the sounds will then play all at once in one screeching playback.
My question is, are there any obvious reasons as to why this would happen?
I've tried several things but because I can't consistently reproduce the issue it's hard to find the cause. The sounds are used throughout the application, so I load them in app.xaml.cs into an application scoped static collection. I call SoundPlayer.Load() to ensure they're loaded into memory straight away.
Like I said, this never stops working completely. The play backs seem to pile up until navigating to another page where they all play at once.
One other thing that may have an impact is that I am displaying a webcam feed in the application. The webcam feed is loaded using the DirectShow.NET library. I'm not sure if loading graphs can have any adverse effect on the playback of sound.
I suppose the web cam is updating a UI element which will cause the UI thread to be pretty busy, in that case you probably do not want to use SoundPlayer.PlaySync() or SoundPlayer.Load which both block the current thread.
Instead try SoundPlayer.LoadAsync() and SoundPlayer.Play() which use a separate thread.
I have a WPF application that is doing some serious work (doing some calculations) when a button is hit. I wanted to add a 'busy animation'. However, the application is so busy doing its work that the animation is stopped until the calculations are finished.
The serious work should always be handled in a separate thread otherwise the complete user interface may be blocked. So you are unable to click anything and not even close the application.
If it is possible you should also try the make small chunks of work and give the rest of the application time to "take a breath" and not do all work at once. It's not always possible but some work can be managed that way.
Are you running your "serious work" in the UI thread? If so, you need to move the work to a separate thread if you still want the UI to be updated.
I'm building a single window WPF application
In the window is a list items (which are persisted in a database of course)
Periodically I need to start a background task that updates the database from an Atom feed. As each new item is added to the database, the list in the UI must also update to reflect this. I don't want this background task to slow down the UI but at the same time it needs to interact with the UI.
Having read loads of articles and seen lots of simple examples, I am still unsure of the best way to implement this.
What I think maybe I could do is:
On the Window_Loaded event, create a DispatchTimer.
When the Tick event fires, call UpdateDb() method.
UpdateDB() will get the items from the Atom feed and add to the database. As I iterate through each item I will call another method to rebind the list to the database so that it "refreshes".
When all the tasks are finished reset the DispatchTimer ??? (not sure if this can / needs to be / done).
Remember, this is background task so a user could be using the UI at the same time.
How does this sound?
Thanks.
This sounds suboptimal because you're doing database connectivity on the UI thread. When the Tick event fires on the DispatcherTimer, handlers will execute on the UI thread. You need to minimize the amount of work you do on this thread to keep the UI responsive, and you definitely shouldn't be doing IO-bound work on this thread.
I would probably have a data service whose responsibility is to update the database and raise events as changes are made. Your UI layer can attach to these events and marshal to the UI thread to apply changes. To marshal to the UI thread, you just need to call Dispatcher.Invoke.
Regardless of your specific approach, the key is to do as much as you can (including any database access) on a separate thread. Marshal back to the UI thread as late as possible and do as little work as possible on the UI thread.
One other thing to note is that WPF automatically marshals changes to scalar values for you. You only need to marshal changes to collections (adding/removing/replacing items).
Your approach would work.
You'd start the timer when the app loads. For each tick of the timer, you start a thread to update the database. Once the database update has happened, you can call .BeginInvoke() on your UI objects to update the UI on the presentation thread (that will be the only time your UI should be affected).
I'd use a System.Threading.Timer, which will call a specified method at a specified interval on a threadpool thread, so no need to create an additional thread, do your db work with that and marshal back to the ui thread as needed.
WPF Multithreading with BackgroundWorker by Pavan Podila:
The good news is that you really don’t have to write such a component since one is available already: the BackgroundWorker class introduced in .Net Framework 2.0. Programmers who are familiar with WinForms 2.0 may have already used this component. But BackgroundWorker works equally well with WPF because it is completely agnostic to the threading model.
I have developed WPF Application. In that application iam loading 200mb photos to the listbox.After that Iam adding those images to canvas.While adding photos to canvas after sometime (i.e; after adding 10mb images)iam getting Some error like ----
*****The CLR has been unable to transition from COM context 0x10b46f0 to COM context 0x10b4860 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.*****
Is there any way to increase the performance of my application. I need a solution for this problem.
Any Suggestions for this.
Don't load all 200 mb of photos into the listbox all at once on your UI thread. Will the user be looking at 200 mb all at once? It'll take some work on your part, but you're going to need to do some delayed loading of the images from a background thread.
Take a look at this article (Advanced Techniques To Avoid And Detect Deadlocks In .NET Apps), it may help.
This looks like two questions, the first is that you are loading images in a background thread, but not doing it correctly; thus, the COM error. Double check that you are have a STAThread application and that the image loading thread is not interacting with the WPF dispatch thread incorrectly. Here's a discussion MTA vs. STA; however, WPF needs STA, and it's a loosing battle to fight it.
The second question seems to be how should one do this; that is, loading a bunch of images for display. I would look into using a lazy data binding of the ListView and let the virtualizing presenter that's built into is manage the loading/display of the images.
Here's some docs on using a view-model. The viewmodel could coordinate the image load and provide the ListView with a binding source that would automatically get the application working.
A simpler alternative might be to start up a background thread and load the images into an ObservableCollection<>, bind that to the ListView and let the framework deal with the display.
I second what Greg D said, loading 200mb of images sounds like a recipe for problems.