I have a highly multithreaded application , where threads are started from multiple places and i would like to know if i can hook into the running process and just get alerted whenever a new Managed Thread is spawned. I should be able to get the following information
The parent thread
New thread
the method from which the new thread is started like <className>.<methodName>
The application is in C# 3.5
As far as I know there is no way to detect when a thread starts. The best solution is probably not to create thread directly, but instead do it via a "thread manager" class that will raise an event when it starts a thread.
State should be handle within the thread processing logic.
I suggest you create a wrapper class which wraps the thread logic and reports it's status and other items as needed. I created such a class for a multi-threaded application where I could corral the status of the threads and pipe that information to the GUI in a standardized way.
Of course I had the luxury of designing it up front, to which, you may not have.
Related
I am creating winform to process (convert txt files to tiff) large amount of files. I put all the code behind a button (btnProcess). Is this a good idea? It works but I noticed when I go away from the winform and come back to this I see blank window until the process is complete. I heard about background worker. what is the purpose of background worker?
What you need here is multi-threading. That means that two (or more) threads of code would run in parallel. One of them would be the UI thread, the one responsible for drawing the window. In your case you are running your code in the UI thread and thus blocking the UI rendering while your code is running.
The purpose of the BackgroundWorker is to start an operation on a new thread and is what you need.
BackgroundWorker class
The BackgroundWorker class allows you
to run an operation on a separate,
dedicated thread. Time-consuming
operations like downloads and database
transactions can cause your user
interface (UI) to seem as though it
has stopped responding while they are
running. When you want a responsive UI
and you are faced with long delays
associated with such operations, the
BackgroundWorker class provides a
convenient solution.
The page I linked above contains a complete BackgroundWorker example.
It depends on your application. If this is a single purpose application that is not extremely long and the only problem is the screen doesn't paint. Which is what it sounds like to me, just throw an Application.DoEvents into the loop and be done with it.
I am having problems closing an application that uses WaitForSingleObject() with an INFINITE timout.
The full picture is this. I am doing the following to allow my application to handle the device wakeup event:
Register the event with:
CeRunAppAtEvent("\\\\.\\Notifications\\NamedEvents\\WakeupEvent",
NOTIFICATION_EVENT_WAKEUP);
Start a new thread to wait on:
Thread waitForWakeThread = new Thread(new ThreadStart(WaitForWakeup));
waitForWakeThread.Start();
Then do the following in the target method:
private void WaitForWakeup()
{
IntPtr handle = CreateEvent(IntPtr.Zero, 0, 0, "WakeupEvent");
while (true)
{
WaitForSingleObject(handle, INFINITE);
MessageBox.Show("Wakey wakey");
}
}
This all works fine until I try to close the application when, predictably, WaitForSingleObject continues to wait and does not allow the app to close properly. We only allow one instance of our app to run at a time and we check for this on startup. It appears to continue running until the device is soft reset.
Is there a way to kill the handle that WaitForSingleObject is waiting for, to force it to return?
Many thanks.
Use WaitForMultipleObject instead, and pass 2 handles. The existing one, and one for an event called something like 'exit'. During app shutdown, SetEvent on the exit event, and the WaitForMultipleObject will return and you can get it to exit the thread gracefully.
You need to switch on the return value of WaitForMultipleObject to do the appropriate behaviour depending on which one of the handles was triggered.
Possibly, also, you can set the thread to be a background thread. This will prevent it from stopping your application from shutting down when the main thread terminates.
See:
http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx
This is what I would do...
Use the EventWaitHandle class instead of calling CreateEvent directly. There shouldn't be any need to use the Windows API other than CeRunAppAtEvent (and API calls make code ugly...). Get this working first.
Before creating the thread, create a ManualResetEvent variable that is not initially flagged. Call it "TerminateEvent".
Replace the WaitForSingleObject API call with WaitHandle.WaitAny(WaitHandle[]) and pass an array containing "TerminateEvent" and the EventWaitHandle class wrapping the CeRunAppAtEvent notification.
Your loop can use the return value of WaitAny to determine what to do. The return value is the array index of the wait handle that unblocked the thread, so you can determine whether to continue the loop or not.
To cleanly end the thread, you can call "Set" on your "TerminateEvent" and then "Join" the thread to wait for it to terminate.
'This all works fine until I try to close the application when, predictably, WaitForSingleObject continues to wait and does not allow the app to close properly.'
Any app can close, no matter what its threads are doing. If you call ExitProcess(0) from any thread in your app, the app will close, no matter if there are threads waiting INFINITE on some API/sychro, sleeping, running on another processor, whatever. The OS will change the state of all theads that are not running to 'never run again' and use its interprocessor driver to hard-interrupt any other processors that are actually running your thread code. Once all the threads are stopped, the OS frees handles, segments etc and your app no longer exists.
Problems arise when developers try to 'cleanly' shut down threads that are stuck - like yours, when the app is closing. So..
Do you have a TThread.WaitFor, or similar, in an OnClose/OnCloseQuery handler, FormDestroy or destructor? If you have, and have no vital reason to ensure that the thread is terminated, just comment it out!
This allows the main form to close and so your code will finally reach the ExitProcess() it has been trying to get at since you clicked on the red cross button
You could, of coure, just call ExitProcess() yourself, but this may leave you with resources leaked in other proceses - database connections, for example.
'216/217 errors on close if I don't stop the threads'. This often happens because developers have followed the er... 'unfortunate' Delphi thread examples and communicate with threads by directly exchanging data between secondary thread fields and main thread fields, (eg. TThread.synchronize). This just sucks and is hell-bent on causing problems, even in the app run, never mind at shutdown when a form has been destroyed and a thread is trying to write to it or a thread has been destroyed and a main-thread form is trying ot call methods on it. It is much safer to communicate asynchronously with threads by means of queueing/PostMessaging objects that outlive both of them, eg. objects created in the thread/form and freed in the form/thread, or by means of a (thread-safe), pool of objects created in an initialization section. Forms can then close/free safely while associated threads may continue to pointlessly fill up objects for handling until the main form closes, ExitProcess() is reached and the OS annihilates the threads.
'My Form handle is invalid because it has closed but my thread tries to post a message to it'. If the PostMessage excepts, exit your thread. A better way is similar to the approach above - only post messages to a window that outlives all forms. Create one in an initialization section with a trivial WndProc that only handles one const message number that all threads use for posting. You can use wParam to pass the TwinControl instance that the thread is trying to communicate with, (usually a form variable), while lParam passes the object being communicated. When it gets a message from a thread, WndProc calls 'Peform' on the TwinControl passed and the TwinControl will get the comms object in a message-handler. A simple global boolean, 'AppClosing', say, can stop the WndProc calling Peform() on TwinControls that are freeing themselves during shutdown. This approach also avoids problems arising when the OS recreates your form window with a different handle - the Delphi form handle is not used and Windows will not recreate/change the handle of the simple form created in initialization.
I have followed these approaches for decades and do not get any shutdown problems, even with apps with dozens of threads slinging objects around on queues.
Rgds,
Martin
Of course the preferable way to solve this is to use WaitForMultipleObjects, or any other suitable function that is able to wait for multiple criterias (such as WaitForMultipleObjects, MsgWaitForMultipleObjects, etc.).
However if you have no control over which function is used - there're some tricky methods to solve this.
You may hack the functions imported from system DLL, by altering in memory the import table of any module. Since WaitForMultipleObjects is exported from kernel32.dll - it's ok.
using this technics you may redirect the function caller into your hands, and there you will be able to use the WaitForMultipleObjects.
I have a c# .NET multi-threaded application that is freezing the interface. What is unusual about this is that the interface does not freeze unless I let the system sit idle long enough for the screen saver to start (which requires me to reenter my password to re-gain access to the system). When the interface becomes visible again (after I have successfully entered my password) all the windows are white. I can see the window titles, move the windows around, minimize them and such, but the screens are not repainting. When I break all and enter the debugger, the call stack has Application.Run(), external code, and then "in a sleep, wait, or join". I put break points in all four of the threads I open and they are still running, it is just the main app's UI thread that is blocked. When I look at my thread list, what was my main thread and my four worker threads now consists of my main thread and 11 worker threads. I didn't open this many threads so it must be the serialport class.
Now let me describe my program.
My main app allows users to collect and monitor data from serial ports. I have implemented this in the following way. When a connection is desired, a button is pressed on the main app which calls a function in a DLL which opens a status window and then launches a thread which monitors the serial port. When that function returns, the main app launches a thread to monitor a queue created in the DLL when it is initialized. When data is received from the serial port, the data is parsed and then the status window is updated (via a delegate) and the data is pushed onto the queue. When the main apps worker thread sees data in the queue it retrieves it and posts it in a list box on the main app, using a delegate. In all cases I use BeginInvoke to call these delegates.
My DLL contains two libraries for the two different types of equipment it can communicate with.
This problem occurs when I have a connection to two devices; hence the four worker threads two for each device. The DLL itself is setup as a comm object so I can access it easily from a C++/MFC app and a c# app, both of which utilize it.
I found that if I add code to the thread inside the DLL so it calls Application.DoEvents() every 30 seconds, the interface will be frozen for about 30 seconds and then resume activity like normal. I figure something is blocking the main thread and forcing DoEvents() to fire seems to break the lock, but I have no idea what might be causing this lock. This is not a solution, just something of interest.
I would appreciate any suggestions you might have. Thanks.
I found that if I add code to the thread inside the DLL so it calls Application.DoEvents() every 30 seconds, the interface will be frozen for about 30 seconds and then resume activity like normal. I figure something is blocking the main thread and forcing DoEvents() to fire seems to break the lock, but I have no idea what might be causing this lock. This is not a solution, just something of interest.
I would recommend running your program under the new Visual Studio 2010 Concurrency Profiler. This will show you, at runtime, which threads are blocked, and which objects they are waiting on. Thread contention is explicitly marked and highlighted for you.
You can use this to easily determine what code is causing the deadlock on your UI thread.
Try changing your Thread Start code to Thread.Start() instead of BeginInvoke(). BeginInvoke does not keep threads tryky seperate from your UI, as it and it may be interacting strangely with DoEvents. You can read up on BeginInvoke and how it works here: http://www.codeproject.com/KB/cs/begininvoke.aspx
Also, DoEvents is NEVER necessary in an application, and can cause a lot of unexpected behavior. Use threadding with UI calls wrapped in a Control.Invoke(...) statement. If you're using .NET 3.5+, you can make this easy with delegates that look like this: Invoke((Action)delegate() {*code goes here*});
I have an XNA application, and I need to redirect the input queue into a custom thread, instead of having it available only in the main thread. Is there an alternative to AttachThreadInput?
I did some searching on this, and I don't think you're going to find a great way to solve this. This post indicates that it may be possible if you "make a new input class, register those events in my games main thread, then start the thread to begin polling."
The general consensus from these two threads (including the one you started on the XNA forums) indicates to me that trying to send keyboard input to a different thread probably isn't the best idea, and that, if possible, the main thread should just handle the keyboard input and the other thread can read the input from the main thread's shared storage. An alternative would be the main thread telling the secondary thread to do certain functions based on what input it received.
Keyboard access from other thread
Keyboard Input on Another Thread
I'm not quite sure what you're asking, but I'll try to answer.
If you're trying to create a multi-player game and want input for each player to be handled by a thread you have to do the following:
Create the XNA objects related to Keyboard/Mouse/Gamepads in the main
execution thread of your
application
Pass the objects by reference to your custom input handling thread.
Threads share memory with the processes that spawn them, so any changes made to the object from inside your custom thread will be automatically accessible outside the thread by using your referenced object.
Hope this helps.
I currently have a thread that listens for data from the network and then runs rules on it. I then want to pass the data to the GUI. I am worried about having a deadlock in the GUI. I cant figure out were to put the mutexes on the GUI side. I am also using c# and dotnet 3.5.
What I have come up with is
1) Using a timer to create an event and dump the thread. Worried about performance.
2) Use an intermediary event to copy the data to GUI.
3) Dig in and figure out thread safe way of using GUI.
What do you think is best way to proceed?
Edit: Here is the solution I am using. I pass in the changed element and then protect the big object with a mutex. I use helper function to switch threads using InvokeRequired then BeginInvoke with a delegate. Pulled from reading the answers and then following links until reaching Threading in Windows Forms by Jon Skeet.
delegate void UInt32ParameterDelegate(UInt32 n);
public void UpdateLocation(UInt32 n)
{
if (InvokeRequired)
{
// We're not in the UI thread, so we need to call BeginInvoke
BeginInvoke(new UInt32ParameterDelegate(UpdateLocation), new object[] { n });
return;
}
// Must be on the UI thread if we've got this far
this.engine.location.UpdateBusy.WaitOne();
// do the work in here
this.engine.location.UpdateBusy.ReleaseMutex();
}
Synchronization is very easy in Windows Forms. You can call Control.Invoke() in the background thread. The thread will stall until the delegate has finished running on the UI thread. No sync required at all.
If stalling the thread is a problem, use Control.BeginInvoke(). You'll have to protect the object(s) you pass to the delegate with a lock if the thread might alter them while it continues running. That's rarely the case in a producer-consumer scenario, the thread can simply create new objects.
Do make sure that you don't Invoke() too often. Do it more frequently than about 1000 times per second and the UI thread will stop pumping Windows messages, being bogged down by handling the invoke requests. Since it is human eyes you're trying to please, invoking more than about 25 times per second is just wasted effort. Pool intermediate results in a collection object.
I hope I understand your problem correctly.
After the background thread reads the data and does whatever it wants, it should use Invoke to call a method on the GUI thread. That method would update anything that should be updated in the GUI.
Never read from the network on the GUI thread. It's only a matter of time before your application runs during a network outage and your GUI hangs as a result. This will really frustrate your users.
In your situation I think the best approach is to have a background thread complete the read operation. Then take the resulting data and move it back to the GUI thread via a SynchronizationContext Post or Send method.
you should just pass an event from your network thread to your UI thread.
then cross threads using begininvoke so you don't get a cross thread exception.
Need help getting info across a UI thread and another thread in C#
You could use a backgroundworker that will process the datareading in a background thread and when it's done you can end the backgroundworker triggering it's RunWorkerCompletedEventHandler. In the RunWorkerCompletedEventHandler you can update your GUI thread with the result.
Isn't easier to just throw a delegate who raise an event that inform the form to refresh itself?