I want to create a new instance of a form in a BackgroundWorker. I've noticed that when I do this, the newly launched form freezes.
Why does this form freeze? How can I get around this?
It's freezing because you're creating the form in the wrong thread - there's no event loop running in the background thread.
You should only create or touch UI elements in the UI thread. BackgroundWorker provides some hooks for this, or you can use Control.Invoke/BeginInvoke.
When a form "runs" it needs to have a thread that runs the WndProc and handles incoming messages from Windows. What you should consider doing here is using the Application.Run() method to start up your form. This will do the necessary work to make sure the WndProc is running properly, and I belive you can call this from your Background thread if necessary.
Related
I have a WPF application in which I have a MainWindow under UI thread. I have created a thread in which I create another window. I have to create this window in a thread because it has to be updated continuously. I want the owner of this window to be the MainWindow. So I am using Dispatcher.Invoke to set the owner of this window.
But when I use Dispatcher.Invoke to access Main UI Thread from Thread 2, I get a cross thread access exception.
I'll post some sample code very soon. Until then, if someone has any idea, please share it.
This is my actual problem to which I thought of implementing above mentioned approach:
I have three line charts with 4 line series each in a window which are updated at an interval of 100 ms which I am doing using Dispatcher.Invoke. Because of this, the UI becomes kind of slow and unresponsive sometimes
I have created a thread in which I create another window.
That already isn't a very good idea and is prone to a lot of problems. All windows in your application should be created by the main "GUI" thread.
I have to create this window in a thread because it has to be updated continuously.
There are ways to achieve that without creating the window on another thread. Create your window on the main thread, then use a background thread to update it. That background thread can update your new window by using Dispatcher.Invoke.
If I have a form that has a timer to check for some stuff in its toolbar button and now I use this form as a child form insde another application, does the timer still run? any possible threading issue that might cause it to stop working?
The reason I am asking is that I have such a scenario and the toolbars are not updated if I open this app in another app, wanted to make see if the issue is coming from here and any possible fixes?
A System.Windows.Forms.Timer will raise its Tick event on the same thread it was created on, so if the parent application somehow blocks its main thread, the code in the Tick event will not get run until the thread clears, this might be the cause of the issue you are seeing, however, the rest of the UI should be unresponsive in that scenario as well.
A System.Timers.Timer will raise its Tick event on a seperate thread, however this will be of little use if your UI thread is being blocked anyways, since this would prevent you from updating the toolbar even if the code runs.
I have a C#/WPF application that is going to perform a lot of actions, including UI modifications (it is loading a Macro), but I want to have a modal window with something moving telling to wait.
The load macro work must be performed in the main application thread, but how to I print the modal window as it must be non blocked by the macro loading but in the application thread because it is a UI thing.
Currently I put the LoadMacro in an BackgroundWorker in a Application.Current.Dispatcher.Invoke while displaying my waiting dialog. But it is not satisfying because the two fight each other to update the UI.
So how do I do it ?
You don't need to run the background worker from any dispatcher.
Load your modal window and then kick off the background worker having subscribed to it's ProgressChanged event. You can then ReportProgress on the background worker passing anything you like back to update the model window in the UserState property.
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.progresschanged.aspx
I have multiple forms that popup during an intensive operation. For example, when a form popups asking user for something, and the user clicks OK, the form's graphics stay on the main screen, even though it is closed. How can I make it so that these graphics disappear completely?
I would recommend performing the heavy work in the background (using a BackgroundWorker for instance), so that the GUI thread is not blocked. That way, the forms will be able to peform screen updates while the work is going on.
It sounds like perhaps you are doing intensive processing on your main thread, which is the thread that processes events like painting windows. Instead you should spawn a separate thread for doing your computations/tasks so that your main thread can continue.
Alternatively you can call DoEvents() periodically while doing your processing to allow the form to refresh, but using DoEvents is kind of a cludge in my opinion.
You can call the Refresh() method on the main screen form, which will force a graphics repaint.
When working with console applications, Console.Readline relinquishes processing to the UI from the Main thread and only continues when an event, such as the pressing of the enter button is fired. How do I replicate this functionality (With a Window form as the UI in this case) in windows form application?
You cannot do this directly.
However, you can do it by calling Invoke, as I described here.
Use form.ShowDialog() instead of form.Show()
This will not stop the thread, but it will stop the user from doing other things in the UI until the window is closed.
Now that you have explained what you want to do...
It would be better to use a BackgroundWorker, keep the GUI active, but disabled and presenting a progress bar + cancel button, until done.