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.
Related
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.
We have a Windows service that calls a 3rd party method that can hang when improperly configured by the end user, which is difficult to test for beforehand. We're handling this risk by calling the method in a Task with a timeout:
private int? FooWithTimeout()
{
var timeout = TimeSpan.FromMinutes(1);
var task = Task.Run(Foo);
if (!task.Wait(timeout))
{
Log("Foo timed out...");
return null;
}
if (task.IsFaulted)
{
Log("Foo threw an exception...");
return null;
}
return task.Result;
}
The 3rd party method blocks forever waiting for input from a resource that cannot respond. It does not support cancellation in any way, shape, or form, nor does it have a built-in timeout. Our concern is that as the service runs these tasks will continue blocking and slowly accumulate, eventually consuming a large amount of resources.
Is that a valid concern? Do we need to abort/dispose the tasks in some way? If so, what is the correct way to do so?
Addendum: The 3rd party in question is Crystal Reports. It hangs when asked to print to a printer that requires some sort of additional input from the user (for example, Microsoft XPS Document Writer will prompt you for where to save the file if you print to it). And by hang, I mean it attempts to show a user prompt to get the additional input, but it's in a Windows Service so nobody ever sees the user prompt and it waits forever for a human being to tell it how to print. We allow end users to configure which printer the service attempts to print to, and there isn't really any way to tell if a given printer requires additional input short of attempting to print to it.
Our concern is that as the service runs these tasks will continue blocking and slowly accumulate
This is a valid concern. You can reduce the consequences of that by starting those tasks on a special thread-pool that uses small stacks. That way there is less memory usage. But it's not a complete fix. If you app must function for a long time (not a GUI app intended for a few hours of use) then this solution will prove unacceptable because eventually the app will suffer from resource exhaustion.
.NET has no way to terminate an uncooperative thread. You need to run these actions in their own processes. You can then terminate those processes safely.
Using AppDomains might be safe as well but it's less certain. It's possible that per-process state is being corrupted when an AppDomain and threads in it are aborted. Also, not all thread can be aborted. In particular IO operations.
Using separate processes is also not a guarantee that no state corruption will result from termination. But in practice most corruptible state live in memory. Process termination likely clears all inconsistent state.
One approach could be to create separate thread which would monitor for any newly created windows - if any new window is created - thread would try to forcefully to close them.
Enumerate windows:
How to enumerate all windows belonging to a particular process using .NET?
And close non wanted windows:
How to use WM_Close in C#?
May be will not work, just a proposal... :-)
I have developed one application in C#.net 3.5 and VS 2008, which contain many controls such as tab, textbox, objelistview, gauges, zedgraph.
My application is intended to communicate on serial port and update the data on said ui. To achive this i am using another timer thread.
Its 24X7 running application, but sometime it just freeze and timer thread stops executing automatically, i can see the sceen but can't click anywhere and simply i need to restart application to make it run again.
Please note i dont see application not responding message or likewise, it just simply freeze.
If any one can provide any inputs for the same it would be great.
You may have memory leaks or too many uncolsed resources. While your application is freezed see Task Manager and check Memory and CPU usage. They can help you gueesing if too many of RAM is used or if your application consumes too many CPU processing power.
In your application consider disposable objects. Try to dispose them correctly. After opening a serial port don't forget to close it again. Also you can use logging mechanisms to see at what point your application freezes.
Try implementing a watchdog using System.Threading.Timer and check if thread responsible for communication is responsive. Also, I'm not sure what do you mean by "another timer thread", but again, you should use aforementioned class to track time between datapolls and use callback method.
Please also remember, like afsharm said, that you need to free resources you don't use anymore, so either get one handle on your COM port and use it or just release it everytime update has ended.
I wrote a C# NET application (Console app that is run as a Service) that manages a Java process (Minecraft Game Server), and our Web Panel software manages my application. When the Java process stops, my application stops itself, and when my application stops, it stops the Java process.
The issue I am running into is that I deployed the software to all of our machines after extensive bug testing, but there seems to be a bug we missed where it is NOT shutting down the Java process sometimes. This bug is horrible as the Web Software tries to start my application, my application tries to start the Java process, but fails due to it being unable to IP bind (since the old process stayed open) and we wind up with 15-30 bugged Java processes running.
I am using CurrentDomain_UnhandledException to catch my application's crashes and call TerminateProcess().
I am using CtrlTypes.CTRL_C_EVENT and CtrlTypes.CTRL_CLOSE_EVENT to detect my application being closed which also calls the TerminateProcess() function.
I have tried both of the following methods...
static void TerminateProcess()
{
log.LogMessage("Minecraft Process Shutdown.");
SendProcessCmd("stop");
}
and
static void TerminateProcess()
{
log.LogMessage("Minecraft Process Shutdown.");
minecraftProcess.Kill();
}
However, I seem to be missing another way that my C# application is being shut down, because both ways seem to leave a Java process running every once in a while that I can't reproduce locally.
Well, you did not state any question, I’m going to guess you wanted to ask for other ways a process can get shut down, so that you can intercept it and ensure the Java process termination. Simply said: That is impossible (in full generality).
Just look at your own code: You are doing exactly the same thing to Minecraft: Calling TerminateProcess causes the target process to terminate immediately, without any chance to clean up. Should anyone call TerminateProcess on you (e.g. a user killing the process from Task Manager), your process just terminates immediately.
Also, some fatal exceptions are uncatchable, e.g. when your process dies on a stack overflow, you are not told, just terminated.
I guess you’d need to create another process, watching over your process… (Or rethink the whole architecture, creating and killing processes, especially with TerminateProcess, seems a bit rough to me.)
We have a SmartClient built in C# that stubornly remains open when the PC its running on is being restarted. This halts the restart process unless the user first closes the SmartClient or there is some other manual intervention.
This is causing problems when the infrastructure team remotely installs new software that requires a machine reboot.
Any ideas for getting the SmartClient app to recognize the shutdown/restart event from Windows and gracefully kill itself?
UPDATE:
This is a highly threaded application with multiple gui threads. yes, multiple gui threads. Its really a consolidation of many project that in and of themselves could be standalone applications - all of which are launched and managed from a single exe that centralizes those management methods and keeps track of those threads. I don't believe using background threads is an option.
OK, if you have access to the app, you can handle the SessionEnded event.
...
Microsoft.Win32.SystemEvents.SessionEnded +=new
Microsoft.Win32.SessionEndedEventHandler(shutdownHandler);
...
private void shutdownHandler(object sender, Microsoft.Win32.SessionEndedEventArgs e) {
// Do stuff
}
It must be a thread that continues to run preventing your application to close. If you are using threading an easy fix would be to set it to background.
A thread is either a background thread or a foreground thread. Background threads are identical to foreground threads, except that background threads do not prevent a process from terminating. Once all foreground threads belonging to a process have terminated, the common language runtime ends the process. Any remaining background threads are stopped and do not complete.
http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx
When a user is logging off or Windows is being shut down, WM_QUERYENDSESSION message is sent to all top-level windows. See MSDN documentation here.
The default behavior of a WinForm application in response to this message is to trigger the FormClosing event with CloseReason == WindowsShutDown or others. The event handler though can choose to be stubborn and refuse to shut the app down, thus keeping the system running.
Check FormClosing handlers of your applications. Maybe there is something in there. I've seen this kind of stuff a couple of times.
Or maybe the .Net app is ignoring close or quit messages on purpose?
Background threads was a quick and dirty solution, best solution is to use synchronization objects (ManualResetEvent, Mutex or something else) to stop the other threads;
Or else keep track of all your opened windows and sent WM_CLOSE message when main app closes.
You have to give more information about how do you start those GUI applications. maybe you start one thread for each application and call Application.Run(new Form1()); ?
You may also look into creating a AppDomain for each GUI Application
Normally a .Net app would respond correctly- at least, that's the 'out of the box' behavior. If it's not, there could be a number of things going on. My best guess without knowing anything more about your program is that you have a long-running process going in the main UI thread that's preventing the app from responding to window messages.