Cross Thread Exception When Closing Application - c#

I am sometimes getting a cross thread exception when closing my application which uses two threads (main thread and secondary). I think what is happening is that the main UI thread is being disposed while the secondary one is still running, and since the secondary one sometimes invokes things on the UI thread it is crashing.
Do I need to manually close the secondary thread in the FormClosing event?
Thanks for the info.

Do I need to manually close the secondary thread?
No and yes.
No, if your secondary thread is a background thread. You can inspect/set the IsBackground property on your secondary thread. All background threads are are automatically stopped by CLR when there is no foreground thread running anymore. All ThreadPool threads, for example, are background threads.
Yes, however, is when you perform some critical task in your secondary thread and you don't want it to be abruptly stopped. In that case, you will have to implement appropriate logic to stop your secondary thread.

Once you have a long-running dedicated thread, you have to implement shutdown logic for it. Reason is simple: the app is not killed by OS until at least one thread alive. And yes, there is no such thing as "main thread", all threads are equal from OS perspective.
Given that, once your app plans to exit, you must
Signal to the second thread that termination expected
Wait for the second thread until it exits from his thread proc
Now you're free to exit.

The recommended approach in multi-threaded windows application is using Method Invocation instead of directly manipulating controls which were created on another thread. This way you never get Cross Thread Exception. For example you can set a textbox's text like this:
form1.BeginInvoke(new MethodInvoker(()=>textbox1.text = "Hello!"));
For more information see:
http://msdn.microsoft.com/en-us/library/ms171728(v=vs.85).aspx

Related

C# child thread is still working even main thread exit

I happened to read Semaphore class sample as below from msdn:
https://msdn.microsoft.com/en-us/library/system.threading.semaphore%28v=vs.110%29.aspx
It's a console app, however something confused me that child threads are able to work even main thread exits.
From my understanding, when main thread/process exits, all child threads will be terminated, that's why usually we signal and wait child threads to finish before main thread stops.
Am I wrong or the behaviour has been changed in .net due to reference?
If you want the child thread to abort on the termination of the parent thread, it must be set as a Background thread.
t.IsBackground = true;
t.Start(i);
Otherwise, all foreground threads run to completion before the process exits

How to use the same buttons for different threads while multithreading?

I will try my best to describe what I need to know. I'm using C# (WPF .NET 4), multithreading by using a BlockingCollection. The threads contain infinite loops, so they are never going to die and they are going in turns (1st - 2nd - 1st - 2nd etc). While each thread is active it is showing in my GUI "Thread X is active".
Now, I have a couple of buttons on my GUI, but right now when I click randomButton it calls the same method from thread 1 and thread 2.
How can I make it so it calls only the method from the active thread? Is there a way to write something in my thread that basically says "If this thread is active the buttons will only affect this thread"?
I think you have a misunderstanding of threading.
Lets define a Thread:
Thread
A thread is the entity within a process that can be scheduled for execution. All threads of a process share its virtual address space and system resources. In addition, each thread maintains exception handlers, a scheduling priority, thread local storage, a unique thread identifier, and a set of structures the system will use to save the thread context until it is scheduled. The thread context includes the thread's set of machine registers, the kernel stack, a thread environment block, and a user stack in the address space of the thread's process. Threads can also have their own security context, which can be used for impersonating clients.
When you run a method inside a Thread in your application, may it be a Background Thread or a Foreground Thread, you are executing a unit of work in parallel to the applications Main Thread, which in your case is the UI Thread of your GUI.
"How can I make it so it calls only the method from the active thread?"
When you start a Thread, it runs until it has finished execution (either by finishing work or terminating due to an exception or thread abortion). So when you start multiple threads simultaneously, invoking same method, they will all run it at the same time, since they are all active
You can use Concurrent Collections which let you access collections inside a multithreaded environment
I suggest you read more about processes and threads here and here

How can I lock UI while running the long running process in the main UI Thread in WPF (code in C#)

Actually, I cannot run the long running process in the Background thread. The long running process gets its input directly from the UI and then it has to save any modifications in the database. So, this long running process is unable to access the input in the background thread despite being written inside the Dispatch code(given below):
this.Dispatcher.Invoke((Action)(() =>
{
...//The long running process inside background thread.
}));
My basic is to prevent the user from clicking anywhere else while the long running process is running. So, is there any other way by which this can be done?
I would do it this way:
Make a "global" (seen for UI thread and background thread) object of one of concurrent types. You can make it as singleton or pass an object to both threads
All the long running thread does is reading data from concurrent object and process them.
If main thread (or any other) need to do anything in background simply adds it to the concurrent collection.
This kind of approach in concurrent programming is called Producer-consumer problem

Control.Invoke() stucks

I know there are several threads concerning this topic, but I think mine is different.
In my application I open a form where the user can input some parameters for a upcomming printing. This printing is supposed to be run in a background worker. So I fire that background worker with the event "OnFormClosing".
Within that background worker I need to access the GUI and change/read it, so I need a control.Invoke(). "Sometimes" the Invoke keeps stuck at the invoke call itself and doesn't execute the delegate. My main thread is working fine and is not blocked. I still can interact with the GUI doing other stuff. Before posting any code: Are there any other conditions for executing a control.Invoke() other than
The main GUI thread is not blocked
The contorl must exist, the handle created and not be disposed
The main thread doesn't need to be free and exactly the invoke is called correct? It should continue once the main thread is idle...
Thanks for any help
Update:
Here is the thread situation during that issue:
The Main thread is executing this:
Application.Run(appContext);
So it is idle.
The worker thread is waiting at this line:
fileName = (string)cbPrintFile.Invoke(new Func<String>(() => cbPrintFile.Text));
which is not executed like I state above. cbPrintFile is a combobox
Invoke is "enqueue and wait for it to be processed". If it is becoming "stuck", that suggests that you have deadlocked, for example because the UI thread is still in an event-handler waiting on the worker. If the code is properly de-coupled, you can probably replace the Invoke with BeginInvoke, which allows the worker to continue after queuing the work. Of course, it would also be good to ensure that the UI is never waiting on a worker. This can be done accidentally if trying to hold a lock (on the same object) in both places. You can investigate simply by pausing the application, pressing ctrl+d,t to bring up the threads, and ctrl+d,c to see the call-stack of each in turn.

C# network application threading causes program to block

I am working on a network application with threading. I have an event handler which results in a form showing on the screen. The problem is that the thread that makes this call blocks right after, so the form that shows blocks as well.
I have hacked this problem by making that function change something in the form it's currently in, and then used invoke required to force the new form onto that thread. This is a terrible hack, what is the right way to make the new form.Show() method go through its own thread.
Note that I have tried just making a worker thread that runs only form.show() but the form disappears right after the call.
Thank you,
PM
You don't want UI elements being created in their own threads. The primary thread that launched your application should be the UI thread. Create and show all elements on this thread. All your heavy, long-time or blocking work should be done on their own threads.
You can use BackgroundWorker to execute a single additional task without blocking your UI and get automatic synchronization when you need to make updates to the main (UI) thread such as to update progress bars or show a final result.
If you need multiple threads doing long-running work, use the ThreadPool. You will have to do your own cross-thread synchronization if you need to update UI elements. There are a ton of answers on how to do that already if that's the route you go.
If you have multiple threads that are being blocked while waiting for something to happen, you should use threads yourself. This will keep the ThreadPool from being starved of threads because they are all blocking. (I believe this has been changed in .NET 4 so if you're targeting that version you can probably easily continue using the ThreadPool in this situation.)
Have you tried placing the blocking call in a BackgroundWorker (separate thread)? When that blocking call is done, your background-worker thread completes (which is handled by your main UI thread). Then in that completed handler you can show your form/message or whatever...
If you haven't tried that then give it a shot. Note that i have not tested this since i dont know exactly what you're doing.
Cheers.

Categories

Resources