System.Threading.Thread - perform operation on it - c#

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.

Related

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.

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.

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.

How can I run a piece of code in the main thread from a different thread?

I am using the class HttpListener as a web server. This server runs on a different thread.
At some point this server needs to run some code but it needs to be executed on the main thread. Is there an easy way of doing that?
Thanks!
The bigger question is:
Why do you need to run it on the parent thread? Is it UI Code modifying the UI? Do you need to be within that thread's context to gaurantee thread saftey?
It might be worth stepping back and re-evaluating your threading model, you may be trying to do things in the wrong place.
I Suggest you read This Excelent Free E-Book on C# Threading and learn about the alternate ways of inter-thread communication and look into the Dispatcher if you're using WPF, as it will help delegate events back to the UI Thread if that's what your intent is.
Quick & Dirty Solution Not really the best way
There's any number of ways to approach this, the simplest would probably to have a list of delegates to execute on the main thread. Each time your main thread spins, you lock the collection (unless you're using the multi-threaded collections) and copy out the delegates & clear the collection and release the lock.
Then you simply run them on the main thread.
The problem you'll run into is if you're using blocking on the main thread, your spin cycle will not pass across your delegates till your blocking stops. So if you're say, blocking while you wait for connections, your code will not run till a new person connects.
You could put the server's listen port on it's own thread to solve this.
To do something on the main thread, you will possibly want to inject it via Invoke(), or in the main loop will have some queue of things to do that will be injected from the 'other' threads, in this case HttpListener.
Your example seems similar to mine, where I have 300 threads handling stream ripping, and they are all 'calling' main thread by putting the string messages into the queue for it. It works like a charm. However, when I did try (I dared, just to see what will happen) to Invoke() from at least 30-ish threads to the main message loop, it was weird, to say the least.
Best: use simple Queue< something >, and enqueue it from the other thread, then dequeue it from the UI thread.

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