This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C# Threading/Lock confusion
I've got following problem: I have monitoring class, which is running it's own thread that writes from queue into file (so the main application doesn't have to wait on IO). But, when main application thread ends (control flow runs after it's last line), the monitor thread ends too, even if it is still running (full queue).
Is there any way, without modifying main thread to wait till the worker thread is done? C#.
EDIT: I cannot modify main thread. I'm writing only 'support' code for huge application with given API (one static method containing what shall I write, where is read from configuration), there is no way how to change threads, main app must not depend on my code.
Switch them around. Make your main thread the one that monitors, and spawn the worker threads (write from Q to file) from there.
Or have the main thread startup threads for monitor and work, and then have the main thread spin and wait (loop until it gets abort/complete notifications from the other threads)
You can use a ManualResetEvent and call WaitOne() at the end of your main execution thread. When the worker thread is done simply signal the ManualResetEvent and it will continue execution of the main thread.
Related
Ok so lets say all I have is the reference of a System.Threading.Thread called thread A and I'm on another thread, lets say thread B. Now I need to execute a bit of code on thread A for a moment, then switch back. Using the reference I have, how can I Invoke thread A to do an action in it?
Well I'm making a c++/cli library. One of my objects has a thread affinity. I enter a method, I need to swap threads like you would in a Dispatcher.Invoke.
void AllegroSharp::Display::DrawToBackBuffer(BitmapImage^ image)
{
al_draw_bitmap(image->GetBitmap(), (float)image->Rect->Position->X, (float)image->Rect->Position->Y, 0);
}
DrawToBackBuffer gets called on thread B and al_draw_bitmap needs to be called on Thread A, which I have a reference to. How can I do this on thread A? Thread B is just some thread that c# spawned when I did a Task.Run in managed code.
Threads run one set of instructions from start to finish. If thread A is already running, it will execute whatever code it's been told to run from start to finish. You won't be able to change what it's running unless it is actively monitoring some shared memory for instructions on what to do next. Typically the way you implement this is by having a thread run in a loop and, inside that loop, check a message queue. Then have other threads add messages to that queue to give the looping thread work to do. There are a lot more details to make it work right, but that's the basic idea.
If, in your particular scenario, thread A is the application's GUI thread, this message passing mechanism is already set up for you, and you can use Control.Invoke (winforms) or Dispatcher.Invoke (WPF) to pass a unit of work to the GUI thread and wait for it to be completed.
Edit: this answer has been rendered less applicable by the addition of new information to the question. Ah well.
For a time/date driven threading application I'm using threads that are created (new Thread() and the threads are all put into a list) in which a method is called that runs for an undefined time (can be 1 second or even a full day). In this method a new (sub)thread can be created (also with new Thread()).
Now, when the threading part of the application is ended (manually or because the program ends) I'm going through my list of threads that I had created and end those manually.
Now as far as I understand it the end of the thread that created the subthread (thus the thread that housed the method where the second thread was created) does not mean the end for the subthread. So my question is: Is there any good way to manage it that a thread kill does cascade to its children (or am I misunderstanding how the threads are working there?).
Edit:
As it was asked: All threads mentioned here are background threads (thus a background process creates a child-background process that shall end when the parent ends).
You should stop your threads in a controlled manner, not letting them be killed by the os (assuming they are background threads) or calling Thread.Abort(), if thats what is meant with "thread killing".
Create a CancellationToken with CancellationTokenSource and provide each SubThread with this token. The methods / loops inside the threads should check token.IsCancellationRequested(). You then only need to call TokenSource.Cancel once (in your main thread).
See How to use the CancellationToken property?
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
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
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.