WPF : Is it impossible to UI load in background thread? - wpf

I've making a some application which build a huge-sized FlowDocument. The elapsed time of building FlowDocument was about 3~4 seconds.
So I like to building FlowDocument in BackgroundWorker, not UI thread. but BackgroundWorker can't return WPF UI object. (It occured InvalidOperationException exception.)
how can i solve this problem?

If you want to build a FlowDocument in another thread, it has to be a second UI-type thread, not a BackgroundWorker. In spite of what the documentation says, you CAN build more than one UI-type thread. However, you cannot create UI objects in one thread, and use them in another. You could save your FlowDocument to disk and then reload it in the foreground UI thread, though.
This article has a good example with two UI threads, and in fact I have used this code to process XPS files in a background thread, very similar to what you are doing. Make sure your second UI thread is set to STA apartment state, and as I said, do not try to use any UI objects created in one thread, in a different thread. It won't work.

Related

Does a winforms event handler happen on the same thread as the caller?

Simple question, though no one at the office seems to know and I can't find a good way to ask google this. In winforms, if you have a function that handles an event (in this case, on a focusLost), does that function happen on the same thread as the one that fired the event?
So if I have a textbox with focus, which is currently running on the UI thread, and I change focus, will the UI thread then run my function?
Yes, the UI thread will execute UI event handlers.
Generally, in Windows programming, you shouldn't be touching UI components on other threads. Windows Forms is designed to work via a single thread. If you need to heavy lifting that otherwise may freeze the UI thread, you spawn a new thread to do the work, then push the changes to the UI thread.
You can use SynchronizationContext.Current to post work to the UI thread. BackgroundWorker is handy for this as well.
I believe that is correct. Normally events are handled on the GUI thread. Here is a link below on how to do so in a different thread.
http://bytes.com/topic/c-sharp/answers/526484-handling-control-ui-events-worker-threads

Cross thread violation while adding UserControl from worker thread to Main UI thread in Winform

I have an application which tab page based. To decrease the startup time I am creating only the tab page which is shown to the user.
After launching the Form, I used BackgroundWorker to create other tab pages. Tab pages contains usercontrols with databinding.
It is working fine. The issue is: With one tab page I am getting cross thread violation. That tab page having databinding also.
So what will be problem in this scenario?
Thanks is advance.
WinForms controls have thread affinity. The means they should be accessed on the same thead they are created on. This is because WinForms is actually just a wrapper around Win32 functionality and the code that manages your windows and child controls in Win32 is not thread safe. Hence your Form and child controls should only be accessed on the same thread they are created.
In your case you should not be creating TabPage instances using a BackgroundWorker thread or indeed any other thread than the main thread which is the location I assume you have the main Form that contains the TabControl you are adding the pages into.
Often developers get lucky and manage to use controls in different threads to which they were created and it does not crash. But this is just pure luck and sooner or later it will start failing.

regarding wpf dispatcher

I am new to WPF and have a question regarding dispatcher and Delegate.Invoke.
In a windows forms application, we can use the invoke method to make changes to UI controls from other threads. This works because invoke “executes the specified delegate on the thread that owns the control's underlying window handle” (as per msdn).
My question is:
Why doesn't Invoke work on WPF? It should be allowed to make changes to UI as the thread that owns the UI control gets to execute the delegate, but still it throws a runtime exception that “a thread is trying to modify an object that is owned by a different thread”.
How does the dispatcher manage to make changes to WPF controls while Invoke fails?
Is it possible to do cross thread programming in WPF without using dispatcher or background worker?
1) why doesn’t invoke work on wpf?
It works fine, but perhaps you're not using it correctly. I suggest you read the documentation
It should be allowed to make changes to UI as the thread that owns the UI control gets to execute the delegate, but still it throws a runtime exception that “a thread is trying to modify an object that is owned by a different thread”
Perhaps you created a UI object on a worker thread, then tried to add it to the main UI on the UI thread ? Without seeing your code, it's only a guess...
2)How does despatcher manage to make changes to wpf controls while invoke fails?
This question is not very clear, but it's probably related to the first question anyway...
3) Is it possible to do cross thread programming in wpf without using despatcher or background worker?
If you need to manipulate the UI from a worker thread, you have to use the dispatcher. BackgroundWorker also uses the dispatcher (indirectly, through the ISynchronizationContext interface) to raise events on the UI thread. There's no way around it.

Dispatcher Thread and UI Rendering Thread working when WPF Form is in Minimized Stat

I have two question regarding WPF Dispatcher Thread.
Does dispatcher thread keeps running when your WPF form is in minimized stat.
I have so many dynamic updated so I flow my updated till winform and then user Timer in winform to update UI. In winform when you minimized winform your Timer will stop working as it is created in UI thread. So my CPU utilization is low. If I have to achieve same behavior in WPF MVVM then how can I achieve that?
Both your questions seem to assume that minimizing your app will somehow stop some of your threads. I don't know where you got that idea, but it's completely wrong. Your UI thread is still running even when you're minimized. How else would it ever process the "restore" command when you un-minimize it? How would Windows be able to get its title to show on the taskbar?
You also seem to think that WPF has a "dispatcher thread" that's somehow special. That's not the case. The Dispatcher takes the place of the Windows message queue, which means it's attached to the UI thread. The thing you call a "dispatcher thread" is the same thing as the UI thread. If you're doing WinForms and WPF in the same app, they both run on the same UI thread (unless you're manually starting new threads and starting your own dispatchers on them, but that's a pretty unusual scenario).
And no, your Timer does not stop running just because your app is minimized (unless you manually wrote code to stop it). Try it: add a call to Console.Beep() in your timer tick event, and then try minimizing your app and see for yourself whether it keeps making noise.
Here's my guess: in your timer's Tick event, your WinForms app calls Invalidate(). When the app is minimized, Invalidate does nothing -- the window isn't shown, so there's nothing to invalidate -- so you see low CPU usage because it's not doing anything.
If you want the same behavior in WPF, your best bet is to add this code to the beginning of your Tick event:
if (WindowState == WindowState.Minimized)
return;

How does Silverlight Background Worker update the UI thread without problems?

I am using the Background worker thread in a Silverlight 4 application. In the ProgresssChanged event handler, I can make calls to the Silverlight UI, but how does this work ? Isn't the background worker thread that fires the ProgressChanged event on a different thread from the Silverlight UI thread ? If so, I thought updating the UI thread from another thread causes exceptions.
Scott
You're right that updating the UI Thread from another thread is a no-no. BackgroundWorker has special smarts to make sure, even though work is being done on a background thread, the ProgressChanged and RunWorkerCompleted events are raised on the UI Thread.
I believe it makes use of SynchronizationContext to do this.

Resources