Is it possible to kill WaitForSingleObject(handle, INFINITE)? - c#

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.

Related

How to allow a process to be shut down cleanly

I have a process that I would like to be able to cleanly shut down from an external process. That is, I would like to give it a chance to clean up it's resources (save it's data etc.) before it dies.
Process.CloseMainWindow appears to be the ordinary way to go, except the process in question doesn't have any windows and I don't want to immediately call Process.Kill because I want to give it chance to clean up first (and a kill process command can't be intercepted by the target process).
So what is the best way to allow my process to be shut cleanly from another process?
I have control over both processes. The process to be shut does have a message loop (Application.Run()) so I would think there would be some message I could post through there.
I have read the msdn article on terminating processes and this article about closing processes cleanly however both mention methods that seem quite sophisticated despite the simplicity of what I am trying to achieve. Given that I have control over both processes I am hoping there's something a bit simpler that can be implemented cleanly in C#. Is there one?
The process to close is not a service, so can't do service stop.
I'm not sure if a .NET message loop supports thread messages, or only window messages. If it supports thread messages, then the terminating app can use PostThreadMessage() to post a WM_QUIT message (or a custom message that the message loop can look for) to the main thread of the target process so it can stop its message loop and exit the app.
Otherwise, have the target app create a named kernel event object using EventWaitHandle and then wait on the event, either by calling EventWaitHandle.WaitOne() in a manual thread, or calling ThreadPool.RegisterWaitForSingleObject() to use a system-provided thread pool. When the event is signaled, you can notify the main thread to exit the app. The terminating app can then open the event object by name using EventWaitHandle.OpenExisting(), and then signal the event with EventWaitHandle.Set().

What is the correct way to have a neverending loop running on a separate thread in WPF?

I'm creating an application that's going to be continuously listening out for incoming signals via TCP until it's either stopped via a button, or the application closes. Being as the PC that the application is running on needs to run quite CPU-heavy stuff, I figured I should run this in a separate thread so that it doesn't hog the CPU.
My thoughts are to use a BackgroundWorker containing an inner-loop in DoWork() that checks the IsCancellationPending flag (this is set via the CancelAsync() method when the user clicks the stop button or exits the application). Is this the best route to go, or is there some other method that's more accepted?
You're doing an IO bound operation, so you shouldn't even be using another thread at all. You should be handling the work asynchronously, in which an event, callback, Task, etc. fires to indicate that you have a message to process, which you can process and then go back to not using any thread at all.
Creating a thread that's just going to spend the vast majority of its time sitting there doing nothing while you wait for network activity isn't a productive use of resources.

Watch dog for blocking function call

I have a closed-source API for some hardware sensor that I use to query that sensor. The API comes as DLL that I use through C# interop. The API's functions are blocking. They usually return error values but in some cases they just won't return.
I need to be able to detect this situation and in that case kill the blocked thread. How can this be done in C#?
The thread they're being invoked on is created through a BackgroundWorker. I'm looking for a simple watch dog for blocking function calls that I can set up before calling the function and reset when I'm back. It should just sit there and wait for me to come back. If I don't, it shall kill the thread so that 1) the API is freed up again and no thread of my application is still hanging around and doing anything should it eventually return and 2) I can take other recovery measures like re-initialising the API to continue working with it.
One approach might be to set up a System.Threading.Timer before the API call to fire after a certain timeout interval, then dispose the Timer after the call completes. If the Timer fires, it'll fire on a ThreadPool thread, and you can then take appropriate action to kill the offending thread.
Note that you'll need to P/Invoke to the Win32 TerminateThread API, since .NET's Thread.Abort() won't work if you're blocked in unmanaged code.
Also note that it's very unlikely your process will be in a safe state after forcibly killing a thread, as the terminated thread might be holding synchronization objects, might have been in the middle of mutating shared memory state, or any other such critical operation. As a result of terminating it, other threads may hang, the process may crash, data may be corrupted, dogs and cats might start living together; there's no way of being sure what'll happen, but chances are it'll be bad. The safest approach, if possible, would be to isolate usage of the API into a separate process that you communicate with via some remoting channel. Then you can kill that external process on demand, as killing a process is a lot safer than killing a thread.

Interface freezes in multi-threaded c# application

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) the interface is locked up. As long as I don't let the screensaver start, then the interface does not lockup.
I should point out that I have two different executables that access the same dll and this problem is occurring no matter which application I use to access the DLL. This seems to imply that the problem is in the DLL as the two applications are completely different (C++/MFC) and (C#/.NET) apart from how they relate to the DLL.
Both exes perform similar steps in how they interact with the DLL. They make calls into the dll to setup the serial port communication, open a status window in the DLL, start a thread in the DLL to monitor the comm port, and then starts a thread in the main app that monitors a stack in the dll.
When data is obtained from the comm port by the thread in the DLL, it is parsed and its results are placed on the stack and then posted to the status window via a delegate. When the thread in the exe sees data in the stack, it outputs the data in the main window, also using a delegate.
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 issue occurs both on my development machine and on a test machine.
I have tried completely removing the output of data to the status window inside the DLL, but that didn't make any difference.
I have been doing multi-threaded programming for years and never seen anything like this; so any advice would be greatly appreciated.
Thanks.
This is a problem that's commonly induced by the SystemEvents class when you have a non-standard way to initialize your user interface. Using threads, specifically. Start your program, Debug + Break All, Debug + Windows + Threads. If you see a thread named ".NET SystemEvents" then you're pretty much guaranteed to get this hang.
Some background: the SystemEvent class supports both console mode apps and GUI apps. For the latter, it should fire its event handlers on the UI thread. The very first time one of its events is subscribed, it creates a little invisible helper window to get the system notifications. It can do this two ways, either by creating the window on the calling thread or by starting up a helper thread. It makes the decision based on the value of Thread.GetApartmentState(). If it is STA then it can create the window on the calling thread and all event callbacks can be properly marshaled to that thread.
This goes wrong if the first window you create is not created on the UI thread. A splash screen for example. That window may contain controls that are interested in a system event like UserPreferenceChanged so they can properly repaint themselves. It now uses the helper thread and any event will be fired from that helper thread, not the UI thread. Poison to any window that runs on the UI thread. The session switch out of a locked workstation (including the screen saver) is for some mysterious reason very likely to cause deadlock. You may also see an occasional painting mishap, the less nasty result of using windows from the wrong thread.
Short from fixing the initialization order, a workaround is to put this in your Main() method, before any windows are created:
Microsoft.Win32.SystemEvents.UserPreferenceChanged += delegate { };
The problem does appear to be related to the ActiveX control is was probably using incorrectly in a form. I switched to using the serial port library in .NET and have not been able to reproduce my problem. Thanks to everyone, especially Hans for their assistance.
I am having the same issue as my PC just hangs up when the screen saver kicks off or I lock my PC and monitor goes to sleep.
I am 95% sure that there are deadlocks appearing in my multithreaded app. Look and identify whether there are any deadlocks in your code.

interface freezes in c# multi-threaded app

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*});

Categories