My Windows Forms Application is still running as task after closing - c#

I have build a C# Windows Forms Application with Visual Studio 2010.
Run and close application is done successfully within a short time.
The process is not running in Task-Manager. As well the debugging process close. No problem occurs.
But if the Application is running a while the program does not close and still leave running in Task-Manager
(I just open the apllication and do nothing else, just wait few hours to reproduce the problem).
In Debug mode i have to click on STOP DEBUGGING button to end process.
What can i do to find the rootcause?

A process ends after all of the foreground threads stop.
In a typical Winforms application, there's one main foreground thread - the UI thread. This stops after the main form (the one used in Application.Run) is closed. Check what your Main method is doing afterwards, or just put a breakpoint there to see if the thread successfuly
You might also have some foreground worker thread if you're doing multi-threading. It's your responsibility to ensure they're all stopped. The tricky part is that some of the classes you're using might spin up such threads on their own, without you knowing about it. The first thing to keep in mind is that any object you create that implements IDisposable should actually be disposed. This might take care of the issue. One example that often causes trouble is System.Threading.Timer (or System.Timers.Timer) - if you don't Dispose it, it will keep your application running indefinitely.
To investigate the problem, you can use the thread list in Visual Studio's debugger (Debug -> Windows -> Threads). Run the application, wait as long as needed, close the form and then pause the debugger. The thread list will show all the managed threads in the process. Look at the location on the threads that are running - double-clicking a thread will switch your debugger view to that thread, and you can then see the call stack. This might give you some insight about where that thread came from, and what code it's currently executing (i.e. why it is stuck). You'll probably see a wait there somewhere (unless it's actually doing CPU work); just look at the call stack (Debug -> Windows -> Call Stack) and look for something to identify.
If you checked all the threads, and you can't see anything suspicious in the call stacks, you might have to do a bit of configuration in the debugger. There's two main things you can try - first, in the call stack window, right click and select "Show external code". If that doesn't help, you might have to disable Just My Code (Options -> Debugger), and enable symbol loading for the modules involved. This is a bit more complicated.

If your project contains more than 1 form than you should go to the events of the last form and double click on "FormClosed" event. After this action sends you to the code, write between the brackets:
Application.Exit();

You can use
Environment.Exit(0);
instead.

If the process is still pending that means you are not disposing your resources properly.
Using Application.Exit() or asking the system to do it Environment.Exit(0) may be logged in the system as an error occurred and you are better to know how to properly close a process than relied on Application.Exit(), if you want to close a thread of your app you have to know how to collect those garbage.
You can re-implement the Dispose method to Dispose services, sockets, streams, almost everything that has a .Dispose available.
public class MyClass: IMyClass, IDisposable
{
private bool _disposed = false;
// ...
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing)
{
// dispose your stuff you created in this class
// do the same for other classes
// some examples
/*
_webClient.Dispose();
_connector.DataAvailable -= ConnectorHasDataComing
_socket.Dispose();
_timer.Dispose();
_taskLogs.ForEach(x => {
x.Token.Cancel();
x.Task.Wait();
x.Task.Dispose();
});
*/
}
// dispose native events
_disposed = true;
}
If you use System.Threading.Thread or System.Threading.Tasks.Task or System.IO.MemoryStream (or other kind of Stream - Writer/Reader), and others that requires a CancellationTokenSource. If you created the ressource in the class when you are disposing the class, use the Token.Cancel() method to let it know its parent is being disposed and .Wait() for it before calling .Dispose()
public async Task Run(CancellationTokenSource cancellationTokenSource)
{
// ...
while (Running) {
if (cancellationTokenSource.IsCancellationRequested) return;
// ....
}
// ....
using (var reader = new WaveFileReader(tempFile))
{
reader.Position = 0;
await reader.CopyToAsync(fileWriter,81920, cancellationTokenSource.Token);
}
}
I found my issue using the Diagnostic Tools when my Debug was still pending on something after closing the app.
If you use CPU Usage you can click on Break All and it set a breakpoint.
You can then see profiler and find what are your top functions, you might find out that your form is disposed but you have a Thread or Task that invokes fields on your form.
For my case, I was using a filewriter and I implemented IDisposable in that class but it sometimes was about or actual doing a transfer of data between a filereader and itself using .copyTo so it was pending without throwing an exception.
After clicking on one the events, click on Go to Source code and place a breakpoint, you may see events that your code is stocked on.
Otherwise, you can use in the same tool the tab Memory Usage to take a snapshot and look at the Heap and Objects diff or the tab CPU Usage and look at a recorded Profile. If find my copyTo issue that way.
You can also run your app with Throw on all exceptions

Related

Prevent windows server from suspending my process

I've developed a program (winforms application, not a service) in C# that runs on a windows server.
The program starts multiple times based on requests from outside the server.
From time to time I see that the program is "Suspended" for an unknown reason. I think it is related to a lack of resources, but not sure.
How can I prevent windows from suspending my program?
Update
To be clear, I know that the program crash and it is OK. What I'm asking is not how to improve performance \ prevent the crash, but how to remove the process from the process list \ prevent this suspended status?
Depends in your hardware/software configuration, it's hard to know where is your bottleneck.
I recommend instead to do Multi-thread/task app where you're able to control threads and asign priority, resources, stop, resume, abort, etc...
use on command console to start and check if happends the same but with the parameter high:
start /HIGH <ProgramPath>
Read more how to change priority on executables
Task Scheduler on windows servers MSDN -> Priority
(It's only an opinion, start digging about others solutions.)
You must set the ServiceBase.CanPauseAndContinue Property to False in the constructor of the service before it is started.
NOTE the side effect is:
If CanPauseAndContinue is false, the SCM will not pass Pause or
Continue requests to the service, so the OnPause and OnContinue
methods will not be called even if they are implemented. In the SCM,
the Pause and Continue controls are disabled when CanPauseAndContinue
is false.
For more information see this Microsoft Doc
There are multiple methods of keeping an app awake.
One method would be to request a deferral and then only mark that deferral complete when you are done.
First you need a deferral object that will remain in scope of your process
SuspendingDeferral deferral
Then you need to override OnSuspending
async protected void OnSuspending(object sender, SuspendingEventArgs args)
{
deferral = args.SuspendingOperation.GetDeferral();
await SuspensionManager.SaveAsync();
}
Then you need to mark the deferral complete when your process is done doing whatever it was doing
if (deferral is not null) { deferral.Complete(); }
Full details can be found in the Microsoft docs
For discussion of other methods see this thread:
How to Disable UWP App Suspension?
Technically the process is suspended but if you look at the memory consumption of 32K you can tell it was not suspended. Your process did crash with an unhandled exception which in turn triggers Windows Error Reporting to take a memory dump.
This involves some kernel magic which keeps a process handle in the kernel (System process) alive. It is not a big deal or memory leak since the process did already terminate. Only the PEB (Process Environment Block) the 32K which includes mostly command line, loaded dlls and environment variables are still there.
I would not worry about suspended processes but why your process did crash with an unhandled exception. This could even be a feature to make programers aware that their process did crash by looking at a looong list of suspended processes in Task Manager ;-).
Since it is a .NET Application you will find a generic error messages that a process did crash in the Application event log and a .NET Runtime logged error message with more exception details.
Perhaps that is already enough to keep you going to fix your issue. If not you can configure WER to create a full memory dump via a registry setting (https://learn.microsoft.com/en-us/windows/win32/wer/collecting-user-mode-dumps). Now you have for each "suspended" process a full memory dump you can load into Visual Studio to look further what was the issue.
To further check who holds your process handle still open you can use handle e.g. ProcessHacker (the better Process Explorer) https://processhacker.sourceforge.io/nightly.php
If something else is happening you can see with this tool who is holding any outstanding handles to your process open. But I strongly suspect it is the Windows Kernel.

Does a Task end if you close the application?

So, I basically have this:
public void DoThisThing()
{
Task.Run(() =>
{
while(true)
{
//Do things
}
}
}
The start of the application basically calls the DoThisThing() method and enters it's own loop.
So, if I just close the application, what happens to this task? Does it just end? does it continue forever? Does it go on for a little bit until garbage collection gets it? Does it have a way to know the application ended?
I googled, but I couldn't get a simple answer, and I feel like there definitely is one.
The first question is, how this task is even executed. According to the Documentation:
Queues the specified work to run on the ThreadPool and returns a task or Task handle for that work.
Each programm starts with one Thread, but can start further. This one is the Main Thread, the GUI Thread and a few other names. As a general rule, if that main thread is ending, all others threads it started are canceled too. This is a OS level rule, to avoid Zombie Threads with infinite loops running all over the place.
The ThreadPool and all it's data - including sheduled and running Threads - will be collected by the "End of Application" Garbage Colleciton. If not, there is propably some OS features to make sure they end as well. But I prefer not to mention those OS fallbacks, as we really should not be using them ever. There are for cases when even the GC can no longe run properly (like Programm being killed via Task Manager).
One of the big challenges of Multitasking and -threading is keeping the main Thread alive, but without blocking it so further I/O can happen. In a GUI you have that work done for you (with the EventQueue).
All which is said below is implementation details - FOR WINDOWS - and mostly undocumented behavior. Do not rely on any of the information.
As an implementation detail, this task will most likely be scheduled to execute on a thread pool thread.
If the task has not started by the time the process exit starts, it won't matter it was queued in the first place.
If the task is currently executing, then according to some of the implementation details of process shutdown on Windows eventually only one thread will be executing which will not be the one executing this task. So, it will be forcibly terminated in that case.
If the task has already finished execution, whether through completion or by throwing an exception then there's no thread occupied by it. However, if the exception was left unobserved then the finalizer - should it get a chance to execute - will throw that. Please note that finalizers are also not guaranteed to execute under any circumstances.
This page should have been visible, but Microsoft's latest screw up in revoking access to old MSDN blogs continues.
Similarly, if you can manage to track the first link on this page then do so and read it.
P.S.: Here's the link for Raymond's blog. What you'll find from both sources is that only one thread continues the process shutdown.
The answer depends on the content of the while loop.
If the loop is running some logic that runs entirely within the scope and control of the main program, then closing the application will terminate everything.
However, if the loop is calling some external routines or operating system functions (Example: write to a file, open a network connection, run a command, start a batch job, etc), then closing the application will not terminate everything.
Based on your sample, in brief: Yes
Tasks that are created by TPL (using Task.Run or Task.Factory.StartNew) by default are background threads. So closing application will immediately terminate them.
This post could be helpfull.

How does Ninject 3 affect object lifetime?

Before I had refactored my project for DI with Ninject, I had a simple test class with a simple method:
public void TestImport()
{
var functionality = new ImportFunctionality();
functionality.Execute();
}
When I ran this "app" (merely a sandbox WPF client app for integration testing my library), I had the "main" window showing up and clicking a button on that window called this TestImport method, which executed and then I could test and debug my code, and when then main window was closed, the app died right there and VS would exit debug mode. Normal stuff.
Then I refactored the whole thing and implemented dependency injection with Ninject, factories and interfaces all over the code; the TestImport method now looks like this:
public void TestImport()
{
using (var kernel = new StandardKernel())
{
kernel.Load<SecurityNinjectModule>();
kernel.Load<HelpersNinjectModule>();
kernel.Load<ImportFunctionalityNinjectModule>();
var functionality = kernel.Get<IImportFunctionality>();
functionality.Execute();
}
}
Now when I run the WPF sandbox/test app, everything works and that's great, except when the "main" window gets closed, the application does not exit anymore and Visual Studio remains in debug mode. I added the call to Dispose() in the hope to fix it, but no luck; wrapping it in a using block doesn't fix it either.
If I run the sandbox without clicking the button to run the TestImport method, and then close the main window, the app shuts down properly.
This leads me to the Ninject kernel object. Could it be holding on to its resources somehow despite the Dispose() call? Then how do I properly shut down an application that's running Ninject 3.0?
EDIT
If I bring up the debug/windows/threads window, I see all instantiated threads either sleeping or "in a sleep, wait, or join", if not "not available"; a thread by the name of .NET System Events is sleeping, waiting or joining; the main thread is "managed to native transition" as well as a thread called vshost.RunParkingWindow - and this is where I got to Why won't my WPF application close properly after it displays a WinForms dialog?. The answer seems to work given it is accepted, but as #BahriGungor says "Using System.Environment.Exit is a lot like using dynamite to make a door because you didn't want to follow the exit signs". And it doesn't say why this is happening.
The interesting thing is, it doesn't happen consistently: sometimes I can break and step through code and when I "F5" to resume, and then close the main window, it does shut down properly. What's going on?
EDIT 2
The functionality brings up a FileDialog, and if that dialog doesn't return an Excel workbook's filename, the import window doesn't show up. I've narrowed it down to this:
If the import view is shown, no matter how it is closed after closing the main app window VS will properly exit debug mode.
If the import view is not shown (i.e. the FileDialog doesn't return anything editable) then VS will not exit debug mode after closing the main app window.
Your DI should have a composition root where 99% of your DI code lives. Factories should be the 1% case of dependency injection. For WPF that is the onStartup method.
Also I don't see anywhere in your code where you specify a lifetime management part of DI. If you aren't specifying a lifetime management aka Bind<Samurai>().ToSelf().InSingletonScope(); then you may be getting no lifetime management and no disposal. Here's the information on scopes for ninject.
You say you added a call to dispose somewhere along the way, but if you have event listeners set up without weak references there can be a memory leak leading to a lack of disposal.
Finally did you follow the other answer on your linked System.Environment.Exit question?
Check the Application.Current.Windows collection in the debugger to find the offending window. https://stackoverflow.com/a/7349650/57883
Have you tried using other win forms dialogs or just the one to see if it is reproducable?

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

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.

C# Adding code to FormClosing event disables X on MdiParent

I have two background threads and a thread to handle minimization running on my WinForms Application. When the program closes, I use this method.
private void MyForm_Closing(object sender, FormClosingEventArgs e)
{
if(labelsUpdaterThread.IsAlive == true)
labelsUpdaterThread.Abort();
if(printNotifyThread.IsAlive == true)
printNotifyThread.Abort();
if(minimizeThread.IsAlive == true)
minimizeThread.Abort();
}
labelsUpdaterThread and printNotifyThread run all the time. MinimizeThread, as you might guess, only runs when the parent form is minimized. Here's my problem:
When the thread.abort methods are called in my above method, the "X" on the top right of my MdiParent form doesn't do anything. Clicking it has no effect.
When the thread.abort methods are NOT called in my above method, closing the MdiParent will sometimes throw exceptions because the Threads are still trying to access resources on the MdiParent that are no longer available, even though they are background threads!
I'm unsure as to why this is happening, doesn't make much sense to me. Thanks in advance for any help!
I agree with Paul Alexander's answer in that you should never call Thread.Abort, it's a horrible way to handle synchronization.
Additionally, you have a horrible separation of concerns here. The threads should not access resources in the form directly. There should be some sort of abstraction/shared-state in between, which is modified and read by both sides (the thread and the form, so make sure to make the instance thread-safe).
That said, if you couldn't make those changes then in the Close method, call the Thread.Abort methods in another thread with a try/catch statement around each. Log the error(s) somewhere at least.
In performing the calls to Thread.Abort on another thread, you don't block the UI thread, as the calls to Thread.Abort are not guaranteed to be instantaneous, and blocking the UI thread will cause the X to be greyed out while the UI thread cannot process Windows Messages (it also helps to guide you to a better separation of concerns).
However, you should move to abstract out the resources that are shared between the form and the thread, as well as provide a proper cancellation mechanism.
If you abstract out the resources to a class that shares the state, then your form doesn't have to do anything on close, the thread call stacks have a reference to the object that has the state and you can then call abort on those threads without worrying about the form and the threads sharing anything.
From there, you can then introduce a proper cooperative cancellation mechanism (cooperative cancellation, which Task supports in .NET 4.0, if that's available to you).
The Abort calls are probably throwing exceptions. Make sure that the pointers are valid and threads are still valid (not disposed) before calling abort.
And, in visual studio, open Debug\Exceptions... and set a check in the 'thrown' column for all exceptions so you see when something goes wrong.
First, Delete the calls to .Abort() and never use them again. Threads should never be terminated by calling Abort. It basically crashes your thread and doesn't give it a chance to release any resources properly or free any system handles. Instead create a ManualResetEvent and check that in your threads. When the event is set, they should terminate.
Thread1
while( ! _stopEvent.WaitOne(0) )
{
...do my thready work
}
Then in closing
private void MyForm_Closing(object sender, FormClosingEventArgs e)
{
_stopEvent.Set();
labelsUpdaterThread.Join();
...
}
If you don't care if the threads terminate properly on application exist, just set IsBackground = true and they'll be terminated automatically when the application exits.

Categories