Blocking main thread when calling one method while another one is running - c#

In my application there is a ListView with files and folders. User can load them on server. Loading is performing in separate thread but I show the state of the process in a progress bar on the Form, using Control.Invoke(ShowProgressMethod... method, so ShowProgressMethod is called on the Main thread.
Everything works fine, but when I try to do something else in the Main thread (for example delete one file), the UI is blocked. It is usually happend when process is refreshed in ShowProgressMethod and during this I called another method from the same thread.
How can I fix this?

Related

Why is my RunWorkerCompletedEventHandler able to invoke the main thread multiple times in parallel?

My BackgroundWorker's RunWorkerCompletedEventHandler invokes a function in my main thread, which shows a MessageBox dialog. I tested what happens if I invoke the BW periodically (with a Timer) and I don't understand why this causes me to get multiple message boxes over time. I mean, shouldn't the GUI thread be blocked during the call to my RunWorkerCompletedEventHandler function?
Whenever I close a dialog, the rest of the function gets executed as normal, for every dialog box.
If I replace the MessageBox.Show with a Thread.Sleep, then I don't have this problem. The function calls all get executed one after the other. No second invocation happens during the sleep, like it does with the MessageBox-es.
Why is this unexpected behavior happening for a MessageBox and can I change it to block the thread properly?
Displaying a message box (or closing one) is not an activity that requires continuous use of the UI thread. The UI thread is used to create new UI that represents the message box but it then goes back into (a version of) the message loop wherein it waits for new work to do.
This is why e.g. the message box can be responsive, be moved around the screen, etc, because the UI thread is free to react to the required events.

Cross-threading error/ Unresponsive UI

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.

C# splash screen using a new thread

I have a big winform application that takes long time to load so I wrote a splash screen for it.
The problem is that when I show the splash form from a new thread, the progress bar will freeze 2 or 3 times while loading. But when I do it using a separated process I haven't any problem and it has a smooth motion.
I want to know that what's the difference between a new thread and a separated process in such a situation.
Thanks
Simply think of it as the Main form has it's own thread. When you are doing something on that thread that is task intensive, it doesn't get a chance to update the UI. However, when you create a new thread, you are in effect creating a new worker that can update the splash screen UI, while the Main form's thread is performing its workload.
A process is an executing instance of an application. For example, when you double-click the Microsoft Word icon, you start a process that runs Word. A thread is a path of execution within a process. Also, a process can contain multiple threads. When you start Word, the operating system creates a process and begins executing the primary thread of that process.
Another difference between a thread and a process is that threads within the same process share the same address space, whereas different processes do not.
It could be because the UI for the splash screen needs to be in a completely separate thread from the main window with a totally separate Windows message queue.
To run some UI in a different thread from the main thread you will need to start a new message pump for it, because message queues cannot be shared between threads.
To start a new message pump, call Application.Run(yourSplashScreen); from the separate thread. Create your splash screen form from the separate thread too.
Note that you cannot directly manipulate controls in one form from code executing in a different form that you started in a separate thread. You would have to use Control.Invoke() to do so, just like you normally do with multiple threads.
Anyway, if you use a separate message queue like this it could help to prevent the stalling that you're seeing.

Background work that perform UI change and modal dialog

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

How can I flush buffer of form object properties BEFORE a Process.Start is executed?

On a button click, I make several changes to form elements (hiding some, showing some, bringing some to front, etc.). After those form element changes are made, I run an external process with a Process.Start(). However, even those those form element layout changes are sequentially coded before the Process.Start() call, they're not being executed/displayed BEFORE my Process.Start().
How do you force a flush of these layout changes that seem to be buffered?
You could try the Control.Invalidate(true) function on the control you want to be redrawn.
Here is a good post about the difference between Refresh, Update, and Invalidate
Based on the Post, I think you would want to use Refresh over Update to invalidate, then immediately update the control
Try either running the .Refresh method before the process.Start, or run Process.Start in a separate thread, such as:
System.Threading.ThreadPool.QueueNewWorkerItem(new System.Threading.WaitCallback(StartProcess));
void StartProcess(object state)
{
Process.Start(...);
}
By putting the start in a background thread, you allow .NET to update the UI before items in the background thread run. If the Process.Start is in the same thread as the UI, then the UI cannot refresh until all processes in that thread have finished running.
Found answer..
mainFormName.ActiveForm.Update();
Bang bang.

Categories