WPF-C# Synchronizing ThreadPool threads - c#

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.

Related

C# Task.Factory.StartNew Longrunning

I would like to find out why the following needs to be blocked in order to get the console to write:
Task.Factory.StartNew(() => Console.WriteLine("KO"), TaskCreationOptions.LongRunning);
and this does not:
new Thread(() => Console.WriteLine("KO")).Start();
According to C# 5.0 in a nutshell, TaskCreationOptions.LongRunning is supposed to make the task NOT use pooled threads (which are background threads), meaning it should be using a foreground thread just like a regular thread, except with a regular thread, one does not need to Console.Readline or Wait() but with a Task, doesn't matter whether it's long running or not, I always have to block the main thread in some way.
So what good is LongRunning or OnComplete() or GetAwaiter() or GetResult() or any other function which is supposed to render a result If I always have to block the main thread myself to actually get the result?
You're relying on undefined behaviour. Don't do that.
You don't need to wait for a task to have it work - it's just the only way to be sure that it actually completed in some way. I assume you're just using a console application with nothing but the code above - by the time the thread actually gets to the Console.WriteLine part, the main thread is dead, and with it all the background threads. new Thread creates a foreground thread by default, which prevents the application as a whole from exiting, despite the fact that the "main" thread was terminated.
The idea behind tasks (and any kind of asynchronous operations, really) is that they allow you to make concurrent requests, and build chains of asynchronous operations (making them behave synchronously, which you usually want). But you still need points of synchronization to actually make a workable application - if your application exits before the tasks are done, too bad :)
You can see this if you just do a Console.ReadLine instead of waiting for the task to finish explicitly - it still runs in the background, independently of the main thread of execution, but now you give it enough time to complete. In most applications, you do asynchronous operations asynchronously to the main thread - for example, a result of a button click might be an asynchronous HTTP request that doesn't block the UI, but if the UI is closed, the request is still terminated.

C# locking in one thread, calling to releasing in another thread

My scenario:
a few BackgroundWorkers to perform various functions.
one of them, and only once, will have to execute to do a special work first before continue and letting other works to do their job.
I'm using Monitor.TryEnter: do this special work when it's true (locking is successful); when it's false, will wait for the lock to be released.
Problem is that this special work is done asynchronously. I have a listener, and the CompletedSpecialWork method will be called, but the Thread is different from the Thread where Monitor.TryEnter was performed (that is, the Thread holding(locking) the object). I need a way to be able to send a message to the original Thread asking to release the object.
I tried to have a static object of SynchronizationContext, but when I do threadHoldingLock = SynchronizationContext.Current it is null (it is being called from the BackgroundWorker that was able to hold the lock).
My question is: from this CompletedSpecialWork context/thread, how can I send a request to the original thread (holding the lock) to release the lock via Monitor.Exit? I need like a way to send a Invoke to the original thread with Monitor.Exit on it.
Try using either ManualResetEvent or AutoResetEvent.
These can be used to block one thread and then (via function call from a running thread into the blocked thread) allow the block to be reset.
They are syntactic sugar on top of a Semaphore but I like the simplified interface.
Good luck!
By their very nature synchronization objects like mutexes need to be released from the same thread that acquired a lock on them. It would pretty much make any kind of synchronization a crashy hit&miss affair if this requirement didn't exist and all your threads could just randomly release all locks from all threads.
You should look at Event objects to signal simple pulses between threads.

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?

Best way: to implement an interrupt/cancel feature for all your threaded workers

So my question is how to implement cancel/interrupt feature into all (I mean ALL) thread workers in your application in best and most elegant way?
It's not important if it's an HttpWebRequest, IO operation or calculation. User should have an possibility to cancel every action/thread at any moment.
Use .NET 4.0 Tasks with CancellationTokens - they are the new universal cancellation system.
User should have an possibility to
cancel every action/thread at any
moment.
Threading is a practice, not a design... and believe me it has been tried as a design, but it failed miserably. The basic problem with simply canceling any action at any moment is that in a multithreaded environment it's just evil! Imagine that you have a section of code guarded by a lock and you have two threads running in parallel:
Thread 1 acquires the lock.
Thread 2 waits until the lock is released so it can acquire it.
Thread 1 is canceled while it's holding the lock and it doesn't release the lock.
DEADLOCK: Thread 2 is waiting for the lock which will never be released.
This is the simplest example and technically we can take care of this situation in the design, i.e. automatically release any locks that the thread has acquired, but instead of locks think of object states, resource utilization, client dependencies, etc. If your thread is modifying a big object and it's canceled in the middle of the modification, then the state of the object may be inconsistent, the resource which you're utilizing might get hung up, the client depending on that thread might crash... there is a slew of things which can happen and there is simply no way to design for them. In this case you make it a practice to manage the threads: you ensure a safe cancellation of your threads.
Others have already mentioned various methods for starting threads that can be canceled, but I just wanted to touch on the principles. Even in the cases where there is a way to cancel your threads, you still have to keep in mind that you're responsible for determining the safest way to cancel your thread.
It's not important if it's an HttpWebRequest, IO operation or calculation.
I hope now you understand why it's the MOST important thing! Unless you specifically know what your thread is doing, then there is no safe way to automatically cancel it.
P.S.
One thing to remember is that if you don't want hanging threads then for each one of them you can set the Thread.IsBackground flag to true and they will automatically be closed when your application exits.
Your worker threads need a way to check with your main thread to see if they should keep going. One way is to share a static volatile bool that's set by your UI and periodically checked by the worker threads.
My preference is to create your own threads that run instances of a worker class that periodically invoke a callback method provided by your main thread. This callback returns a value that tells the worker to continue, pause, or stop.
Avoid the temptation to use Thread.Abort() to kill worker threads: Manipulating a thread from a different thread.

Categories

Resources