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

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

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.

Cascading thread killing

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?

Cross Thread Exception When Closing Application

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

.NET async, can a single thread time-slice between tasks?

I'm trying to get a grasp on asynchronous programming in C#/.NET. I read an article (link) on Brown University's website for the cs168 course that defines asynchronous programming as interleaving tasks within the same thread. It says, "Now we can introduce the asynchronous model... In this model, the tasks are interleaved with one another, but in a single thread of control", and shows interleaving very clearly in a figure. But I can't seem to get two tasks to interleave within the same thread in .NET. Is there a way to do that?
I wrote some simple apps to try to test this theory, but I'm not sure if I'm doing it correctly. The main program outputs to the screen every so often, using Thread.Sleep() to simulate work. The asynchronous task does the same. If multiple threads are used, the output is interleaved. But I'm trying to test on a single thread.
I have a WPF app that runs everything on the UI thread, but the task and main program always output sequentially. I create and start the task like this:
var taskFactory = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());
var task = taskFactory.StartNew(workDelegate);
I have a console app that starts the task delegate using Task.Run(workDelegate);, but that runs them on different thread pool threads. I'm not sure how to make them both run on the same thread. If I try the same approach I used in WPF I get a runtime InvalidOperationException, "The current SynchronizationContext may not be used as a TaskScheduler".
Multiple tasks won't automatically be interleaved on a single thread. To do that, you have to specify the points in task code where the thread is allowed to cut over to another task. You can do this via a mechanism like await Task.Yield. If you're running on a single thread, the thread will not be able to allow other work to progress unless it explicitly yields.
When you use your TaskScheduler to start every task, the message pump in WPF schedules each task to run on the UI thread, and they will run sequentially.
I have a console app that starts the task delegate using Task.Run(workDelegate);, but that runs them on different thread pool threads. I'm not sure how to make them both run on the same thread.
You would need to install a custom SynchronizationContext into a thread which allowed you to post work to that thread.
You cannot run two concurrent Tasks in the same thread-pool thread. Each thread-pool thread can run one Task at a time. If you want to do two things in one thread, your options what I see now:
1. Combine the two things into one Task
2. Create two tasks and one would depend on the other one. SO in the end they would run sequentially after each other. By default it's not guaranteed that they would run in the same thread though, but you should not rely on that anyway.
It's not clear to me what you want to do. According to the books the UI and the thread of your WPF should do any heavy lifting number crunching work. It should take care of the UI and organize the worker threads/tasks. You would start operations in the background using async.

Threadpool, order of execution and long running operations

I have a need to create multiple processing threads in a new application. Each thread has the possibility of being "long running". Can someone comment on the viability of the built in .net threadpool or some existing custom threadpool for use in my application?
Requirements :
Works well within a windows service. (queued work can be removed from the queue, currently running threads can be told to halt)
Ability to spin up multiple threads.
Work needs to be started in sequential order, but multiple threads can be processing in parallel.
Hung threads can be detected and killed.
EDIT:
Comments seem to be leading towards manual threading. Unfortunately I am held to 3.5 version of the framework. Threadpool was appealing because it would allow me to queue work up and threads created for me when resources were available. Is there a good 3.5 compatable pattern (producer/consumer perhaps) that would give me this aspect of threadpool without actually using the threadpool?
Your requirements essentially rule out the use of the .NET ThreadPool;
It generally should not be used for long-running threads, due to the danger of exhausting the pool.
It does work well in Windows services, though, and you can spin up multiple threads - limited automatically by the pool's limits.
You can not guarantee thread starting times with the thread pool; it may queue threads for execution when it has enough free ones, and it does not even guarantee they will be started in the sequence you submit them.
There are no easy ways to detect and kill running threads in the ThreadPool
So essentially, you will want to look outside the ThreadPool; I might recommend that perhaps you might need 'full' System.Threading.Thread instances just due to all of your requirements. As long as you handle concurrency issues (as you must with any threading mechanism), I don't find the Thread class to be all that difficult to manage myself, really.
Simple answer, but the Task class (Fx4) meets most of your requirements.
Cancellation is cooperative, ie your Task code has to check for it.
But detecting hung threads is difficult, that is a very high requirement anyway.
But I can also read your requirements as for a JobQueue, where the 'work' consists of mostly similar jobs. You could roll your own system that Consumes that queue and monitors execution on a few Threads.
I've done essentially the same thing with .Net 3.5 by creating my own thread manager:
Instantiate worker classes that know how long they've been running.
Create threads that run a worker method and add them to a Queue<Thread>.
A supervisor thread reads threads from the Queue and adds them to a Dictionary<int, Worker> as it launches them until it hits its maximum running threads. Add the thread as a property of the Worker instance.
As each worker finishes it invokes a callback method from the supervisor that passes back its ManagedThreadId.
The supervisor removes the thread from the Dictionary and launches another waiting thread.
Poll the Dictionary of running workers to see if any have timed out, or put timers in the workers that invoke a callback if they take too long.
Signal a long-running worker to quit, or abort its thread.
The supervisor invokes callbacks to your main thread to inform of progress, etc.

Categories

Resources