Cascading thread killing - c#

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?

Related

System.Threading.Thread - perform operation on it

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.

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

Wait for ANY thread to finish, not ALL

I'm starting multiple threads and would like to know when any of then finishes. I know the following code:
foreach (Thread t in threads)
t.Join();
But it will only wait for all threads together. That's much too late. I need to know when one thread finishes, even when other threads are still running. I'm looking for something equivalent to WaitAny only for threads. But I can't add code to all threads I'm monitoring, so using signals or other synchronisation objects is not an option.
Some clarification: I'm working on a logging/tracing tool that should log the application's activity. I can insert log statements when a thread starts, but I can't insert a log statement on every possible way out of the thread (multiple exit points, exceptions etc.). So I'd like to register the new thread and then be notified when it finishes to write a log entry. I could asynchronously Join on every thread, but that means a second thread for every monitored thread which may seem a bit much overhead. Threads are used by various means, be it a BackgroundWorker, Task or pool thread. In its essence, it's a thread and I'd like to know when it's done. The exact thread mechanism is defined by the application, not the logging solution.
Instead of Threads use Tasks. It has the method WaitAny.
Task.WaitAny
As you can read here,
More efficient and more scalable use of system resources.
More programmatic control than is possible with a thread or work item.
In my opinion WaitHandle.WaitAny is the best solution, since you don't like to use it for some xyz reason you can try something like this.
Take the advantage of Thread.Join(int) method which takes millisecond timeout and returns true when thread is terminated or false when timed out.
List<Thread> threads = new List<Thread>();
while (!threads.Any(x=> x.Join(100)))
{
}
You can alter the timeout of Join If you know how long it will take.
My answer is based on your clarification that all you have is Thread.Current. Disclaimer: IMO, what you're trying to do is a hack, thus my idea by all means is a hack too.
So, use reflection to obtain the set of native Win32 handles for your desired threads. Your are looking for Thread.GetNativeHandle method which is internal, so you call it like thread.GetType().InvokeMember("GetNativeHandle", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic, ...). Use a reflection tool of your choice or Framework sources to learn more about it. Once you've got the handles, go on with one of the following options:
Set up your own implementation of SynchronizationContext (derive from it) and use SynchronizationContext.WaitHelper(waitAll: false) to wait for your unmanaged handles.
Use the raw Win32 API like WaitForMultipleObjects or CoWaitForMultipleObjects (depending on whether you need to pump messages).
Perform the wait on a separate child or pool thread.
[EDITED] Depending on the execution environment of your target threads, this hack may not work, because one-to-one mapping between managed and unmanaged threads is not guaranteed:
It is possible to determine the Windows thread that is executing the code for a managed thread and to retrieve its handle. However, it still doesn't make sense to call the SetThreadAffinityMask function for this Windows thread, because the managed scheduler can continue the execution of a managed thread in another Windows thread.
It appears however, this may be an implication only for custom CLR hosts. Also, it appears to be possible to control managed thread affinity with Thread.BeginThreadAffinity and Thread.EndThreadAffinity.
You could use a background worker for your working threads.
Then hook all the RunWorkerCompleted events to a method that will wait for them.
If you want that to be synched to the code where you're currently waiting for the join, then the problem is reduced to just synchronizing that single event method to that place in code.
Better yet, I'd suggest to do what you're doing asynchronously without blocking, and just do what you want in the event.
Would you consider wrapping your thread invocations with another 'logging' thread? That way you could log synchronously before & after the thread run.
Something like this pseudo-code:
int threadLogger(<parms>) {
log("starting thread");
retcode = ActualThreadBody(<parms>);
log("exiting thread");
return retcode;
}
If you have more information on the thread started, you could log that as well.
You could also take the thread function as a parameter in the case where you have multiple types of threads to start, which it sounds like you do.

WPF-C# Synchronizing ThreadPool threads

I have a code design as follows. The GUI thread makes three ThreadPool.QueueUserWorkItem calls. The third call waits for the first 2 calls to finish using AutoResetEvents. However, when one of the two threads throw an exception, I want the third thread to end and the control to return to the GUI thread. Any ideas on how I can go about doing this?
What's wrong with setting the events not only when the threads finish but also when they throw an exception?
Just use one autoreset event which is set when either thread completes (either normally or with an exception). Have two integer variables (shared by all threads), threadCompletedNormallyCount and threadCompletedAbnormallyCount. When a thread completes it increments one of these two variables using Interlocked.Increment to indicate how it completed, then sets the event.
When the third thread awakes it can check these variables to see whether it needs to exit (i.e. both threads have completed normally or at least one abnormally, though what do you intend to do with the uncompleted thread in the latter case?). If only one thread has completed normally it should sleep again.
Why don't you use the Parallel Task Library to sync your threads and have the outcome run through the dispatcher thread by storing a ref to the dispatcher in one of your tasks then use
Dispatcher.BeginInvoke to execute the last step on the UI thread?
I like the idea of using the Parallel Task Library. You can set a barrier to wait for the two threads to finish and a Cancel Token to easily cancel either or both. IMO, the PTL has better exception handling too.

Wait for all worker threads to end [duplicate]

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.

Categories

Resources