I am developing a high performance App that is causing the main process to seemingly stop responding and crash - from time to time - due to overload (I get the Close Application Dialog so the App never exits per se, just freezes, which is annoying)
I welcome any clean way to pro grammatically detect when the App is frozen, so I can use a BAT (or else) to automatically Kill the process and Restart.
Of course, this is a temporary fix while auditing the App, but it comes very handy in the meanwhile.
TieBreaker : BTW, Is there a way to override windows' Exception Screen and just quit the App ???
This is mostly annoying feature most of the time.
EDIT :
FOR GOD'S SAKE : the app IS freaking freezing, THOUGH every single task run in BG Workers and threads !!! And I specified that in comments. Come'on, I am not that dumb. Just that your app runs BG workers does not imply it never freezes ! And As I said, please JUST answer my question, I am not looking for lessons on how to design my App, that I am already working on and I know what has to be done. As specified MANY times, I just need a fix on the server in the meantime.
Thank you.
I'll say it if noone else will :) Make a separate forms app that does-
Process[] prs = Process.GetProcesses();
foreach (Process pr in prs)
{
if (!pr.Responding)
{
try
{
pr.Kill();
}
catch { }
}
}
//then to restart-
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = #"C:\yourapp.exe"
}
};
process.Start();
Obviously oversimplified.
We handle this in a service by having the main service exe be little more than a shell that launches the child threads.
The child threads are then responsible for reporting back to the parent thread whenever they can to record the last date/time they were "seen".
On a regular interval, the service app checks the list of child processes and, if one hasn't been seen for a predetermined period of time (i.e. 2 minutes), but did not report that it had closed down, the parent process will first try to join the thread and shut it down gracefully (usually fails) and then, if that didn't work, aborts the thread.
We have used this approach successfully for many years, starting when an OCR service that we were running would hang constantly due to bugs in the OCR software.
Move all CPU instensive tasks off of the GUI and invoke back to the gui to report any statuses.
The main app should never freeze. I wrote an app that generated over 500 threads (all at once) and managed them as they asynchronously (.net 2) processed multiple database calls. I believe you need to systematically move all processes to a thread safe situation and remove any direct GUI calls.
ADDENDUM How did I run 500+ threads:
Usage of smart locks done from the beginning on all shared data locations. See my blog articlesSmart Resource Locking in C# .Net for Thread Safe CodeC# MultiThreading Using ThreadPool, Anonymous Delegates and Locks
Interface created which specified an action operation with data, error status as a properties.
Threading base class created (for classes in #4 and #5) which created, started and cleaned up thread opertions. No business logic, just a method of handling threading in one location.
Class created based on interface in #2 and also derived from step #3. Class via the interface was required to get data and place data (thread safe via localized lock) and report its status. Class also designed to give up thread cycle if no work done to be done via thread.Sleep(0) instead of busy waiting.
Manager class created (which ran on its own thread and derived from #3).It launched 1-N #4 classes to do work. Each of those instances was placed into a working list.
Manager class simply browsed the working list for instances which reported their work was done if it was done it moved the instance to the done work. Manager class also kept records of the status (thread safe via locks) to exposed properties (as well as any reported errors by the children instances). Manager gave up thread cycle after each run and slept for 250 milleseconds before starting again.
GUI thread had working timers which dealt with getting specific status from the manager. They would extract the data from the manager's properties and invoke back the GUI to target a control (gridview) which reported all statuses and errors.
By doing that, I was able to achieve individual threads doing specific work and if a process ran into a problem it reported it, or it reported success or failure. Those messages bubbled up to the manager which bubbled up to the timers which bubbled up to the GUI. The gui handled no business logic except to start the mananager and timers.
I get that this doesn't help your situation right now and I feel your pain. But until you are able to seperate out the business logic from the GUI and handle error situations in the threads (background workers) and bubble them up to the GUI, you will still have this frustration with the current code.
If something is locking that is a sign that business logic is too tightly coupled with GUI operation and that has to be divorced before you will get the performance you want from the GUI.
HTH
Related
I'm trying to diagnose why my app is freezing up and android is displaying a message that app is not responding. For an unknown reason, messages that should show in logcat output do not when this happens.
I'm looking at using https://github.com/nwestfall/Xamarin.ANRWatchDog to find out what is going on in my app if it becomes non-responsive. The problem is, I don't see anything in call stacks from a c#/managed thread perspective.
All information I've been able to find doesn't work with c#/Xamarin/Android and/or is target the development for desktop/server development. Attempting to get a list of threads gives me a list, but all entries in the list are null. Even if I can a list of the actual threads, how do I get the call stack for each thread?
var threads = Process.GetCurrentProcess().Threads;
Is there a way to get the current stack trace for all managed threads in a Xamarin/Android app?
System.Diagnostics.StackTrace() for the current thread, however you probably don't care about that.
Here's a way to get other threads and get their stack traces:
How to get non-current thread's stacktrace?
If that doesn't work, you can certainly use a method I've used successfully in winforms, a long time ago. Here's the strategy:
ensure all your worker threads have a top-level try/catch with logging you can access
Abort the worker threads and look for the abort exceptions in the logs!
Sounds simple, but takes you straight to a crash. Still you have to get the threads to abort them, see the threadsampler.Start method first few lines in the S/O link above.
If your UI is responsive you can hide this function in an easter-egg activated devtools menu or have a debug menu activated in your configs (you'll want than when your UI apps get non trivial anyway!)
Unfortunately since it's locking up, you'll just have to start a background thread to run this functionality, you could have it ping the UI every second or 20, and abort threads if it locks. Strategy would be to invoke a 'dummy function' on the UI thread:
https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/appmodel/main-thread
and wait for it to come back, e.g., InvokeOnMainThreadAsync, it should do that in 5sec or less otherwise you take action. Apply a timeout waiting for it:
Asynchronously wait for Task<T> to complete with timeout.
Make sure to turn this off in prod!!! Or optionally, activate via switch you can direct users to turn on.
This is the pattern we used in the field for our app, years and years ago.
Full saga:
How do I get the GUI thread of winform?
A newer version of our app does all the work on a background thread and the user gets a chance to cancel if it takes more than 10 sec. However that requires the use of an abstracted UI and the team created a variation on MVVM. Useful as it allows us to deploy a thick client and web app with all the same code - including UI code. Probably not worth the effort for any other apps, and if I had to do that over I'd use javascript for a web app and deploy it to desktop in electron and mobile via cordova, react etc. Oh well.
You're probably beyond this (apologies in advance) but there is the Debug\Windows\Threads tab and if I hang a named thread deliberately in my Xamarin Android app:
new Thread(hangMe) { Name = "HangMe" }.Start();
void hangMe()
{
while(true)
{
Thread.Sleep(500);
}
}
If execution is paused by going to the VS main menu Debug\Break All then there may be some useful call stack info there in the Threads tab.
I understand that things are rarely this simple...
I'm working on about 35 batches updating many databases as a part of our daily process at work. Every batch of them was developed in a single web app. Due to database issues, i have collected all of them in one windows application to make use of DB connection pooling and i have assigned a single backgroundworker for each batch. Reaching to 20 batch in the application, every thing is working good. But when i add any other backgroundworker for any other batch, the application hangs.I think this is because i'm running too many threads in one process. Is there a solution for this problem, for example, making the application working with many processes ??!!!.
Regards,
Note,
I have assigned a single machine for this application (Core i7 cpu, 8 gb ram).
How many databases you have to update?
I think it is more recommended to have the number of Threads as the number of Databases
If your UI is freezing while many background workers are active, but recovers when those background workers are finished processing, then likely the UI thread is executing a method which waits for a result or signal from one of the background worker threads.
To fix your problem, you will have to look for UI-related code that deals with synchronization / multi-threading. This might be places where one of the many synchronization objects of .NET are being used (including the lock statement), but it could also involve "dumb" polling loops a-ka while(!worker.IsFinished) Thread.Sleep();.
Another possible reason for the freeze might be that you are running a worker (or worker-related method) accidentally in the UI thread instead in a background thread.
But you will find out when you use the debugger.
To keep the scope of your hunt for problematic methods managable, let your program run in the debugger until the UI freezes. At that moment, pause the program execution in the debugger. Look which code the UI thread is processing then, and you will have found one instance of offending code. (Whatever there is wrong, i can't tell you - because i don't know your code.)
It is quite possible that different UI-related methods in your code will suffer from the same issue. So, if you found the offending code (and were able to fix it) you would want to check on for other problematic methods, but that should be rather easy since at that point of time you will know what to look for...
I'm working on a Windows application (not WinForms, not Console, not WinService), is just a project with an entry class.
What is the best way, in .NET, to stop an application from exiting the Main method?
I know I can achieve this in console with Console.Read() or I can use EvenWaitHandle.WaitOne() and never call Set().
Is there a better way of doing this?
Thanks for the help in advance.
UPDATE:
This is an overview of the application.
I need to start independent processes (some exe) on demand, containing wcf service. WCF service should listen idefinetly and that is why I need this functionality. The most similar approach I can find is IIS (many w3wp processes running at the same time).
w3svc.exe (IIS windows service) starts many instances of w3wp.exe depending on the number of configured app pools and the requests, it receives.
In my application I want to keep up the processes representing w3wp.exe in the IIS infrastructure, not w3svc. What is the kind of message loop that would keep alive w3wp in .NET?
You can do that in sooo many ways. I personally like this one, as it is very readable and self explanatory:
Process.GetCurrentProcess().WaitForExit();
IIS is a windows service which is why it runs like this. You might look at other options like a single service where you can invoke it via an api and tell it to start another thread or listener. Starting new instances of applications isn't the best option. Typically windows applications have a messagepump, which is a while loop I think...which would prevent it from exiting.
However, you can also follow the example here, which I believe does not close the formless window:
Run Formless Notification User Control?
while(true)
{
// to make it less CPU intensive
Thread.Sleep(1000);
}
Of course, any solution you can think of will not prevent the forceful termination of application by killing its process.
In your update you say that the program is starting several other programs using Process. (It happens to be 'yourself' but that doesn't matter.)
If the program has already done that it doesn't sound like it has any more to do. That process ending won't kill all of the processes it spawned.
You can use the process.WaitForExit() to wait for the processes that you spawn to all exit, rather than just spinning doing nothing, if for some reason you really need to keep the process alive. If there is something that it actually needs to do after spawning the other processes then you'd need to tell us what that is, because if there is something you should be waiting on an event of some sort, which is something you haven't brought up.
Edit: you claim that all the process is doing is "listening". Define that task. If you have a blocking GetNextRequest method then you simply have: while(true){GetNextRequest();}. If it's non blocking, then use use a BlockingCollection<MyRequests> in which the receive method/event hanlder adds a new item to the collection and the main thread had a while loop just like I mentioned before reading from the blocking collection. The point is that you shouldn't ever just sit there and do nothing; you process is doing something, so do that in a while(!done) or while(true) loop. If the method isn't blocking, it's a reasonably well defined problem to solve; just wrap it in a blocking method call.
System.Threading.Thread.Sleep(millisenconds);
I was writing up a long, detailed question, but just scrapped it in favor of a simpler question that I didn't find an answer to here.
Brief app description:
I have a WPF app that spawns several threads, and each thread executes its own WF. What are some of the best ways to handle errors in the threads and WF that will allow user interaction from the GUI side? I definitely plan to handle any low level exceptions in the thread, because I don't want the thread to exit.
Summary of questions:
How have you implemented communication between WF and the thread that starts it? There is WorkflowTerminated, but I don't want the workflow to exit -- I need to fix the problem and let it continue. I assume the only option is using a FaultHandler, but was wondering if there's another way to do it without using an activity block. I am hoping there's a framework out there that I just haven't found yet.
The error from WF needs to get caught by the thread, which then needs to display the error in the GUI. The user will then make a logical choice for recovery, which should then be sent back to the thread, and then to WF. Again, is there something existing out there that I should take a look at?
Even buzzwords / keywords that accomplish what I am describing would be really helpful, and I can do the legwork on researching each of them. However, any additional insight is always welcome. :)
What's worked for me in multi-threaded WPF apps is to have the errant thread invoke a callback method that passes the exception and other info back to the UI thread. Callbacks can have return values, so if your thread can block while waiting for the user to respond, then that can work for you. Remember that the callback will run on the thread that calls it, so any UI updates have to be done via the control's dispatcher. You will have to decide whether all of the threads use the same callback and what kind of synchronization you'll need if there's a chance that multiple threads can throw exceptions simultaneously.
Here's how I ended up solving this problem. But first a little background info:
User clicks a button in the GUI that causes the candy packager to start running. This is done via a command binding in the ViewModel, which then calls a low-level function in the Model. The function in the model launches a thread and executes a state machine.
At some point, the machine will fail. When it does, I compile information about the error and possible (known) recovery methods. I put this into an object and then pass it to the GUI via a callback interface. In the meantime, the worker thread is stuck waiting for an Event to get set.
Eventually, the candy worker will notice the error and will click a button telling the system what to do. This results in two things: 1) it flags one of the recovery methods as the preferred one, and 2) sets the event. Now the worker thread continues on, checks for the preferred error recovery method and transitions into the respective state in the state machine.
This works very well (so far). The part I know is totally lame is the manner in which it checks for the preferred error recovery method. I am essentially setting a string variable, and then comparing this string to a list of known strings. Ultra lame, but I'm not sure of a better way to do this, other than using an enum. Does anyone have recommendations for me?
What I need to know:
I would like to detect when a the main thread (process?) terminates so that I can ensure certain actions are performed before it is terminated.
What I have found myself:
I found the events AppDomain.DomainUnload and AppDomain.ProcessExit. AppDomain.DomainUnload seems to work with non-applications like MbUnit. AppDomain.ProcessExit seems to work with applications but there is a 3 second time limit which I really don't like. Is there more ways to detect when an AppDomain / process terminates?
Background:
I am looking for such an event to ensure my log is persistet to file when the application terminates. The actual logging runs on another thread using a producer-consumer pattern where it is very likely that log entries might queue up in memory and I need to ensure this queue is saved to file when the application terminates.
Is there anything else I should be aware of?
Update:
Changed the above to reflect what I have found out myself. I am not happy with the 3 second time limit during ProcessExit. The MSDN documentation does say though that it can be extended:
The total execution time of all
ProcessExit event handlers is limited,
just as the total execution time of
all finalizers is limited at process
shutdown. The default is three
seconds, which can be overridden by an
unmanaged host.
Does anyone know how to override the default?
More ideas are also highly appreciated!
Follow up:
I have posted a follow up question to this.
You should have an entry point for your application. Normally you can do there some logging when all tasks are terminated:
static void Main()
{
try
{
Application.Run( .... );
}
finally
{
// logging ...
}
}
What exactly do you want to find out?
When the process terminates? (Just because the AppDomain is unloaded doesn't necessarily mean that the entire process is terminating)
When the main thread terminates (If there are other non-background threads, the main thread can terminate without the process terminating (or AppDomain unloading)
So they're not quite the same thing.
Anyway, it is generally dangerous to have log messages buffered in memory at all. What happens if someone turns off the power? Or if I terminate your process through Task Manager? All your log messages are gone. So often, you'll want unbuffered writes in your log, to get messages pushed to disk immediately.
Anyway, another (more robust) approach might be to run the logger itself in a non-background thread. That way, even if the rest of the application terminates, the logger won't, so the process is kept alive. Then you just have to set some flag when the rest of the app terminates, to let the logger know that it too should close once it has written out all pending log messages.
It still won't save you from the case where the system loses power or someone forcibly termianates the process on the OS-level, but it will handle all cases where the application closes normally, and gives you unlimited time to perform clean-up actions (since the process isn't actually terminating yet, it's still got one live thread)
ie. guaranteed to be called and have unlimited time to finish?
Unfortunately, NO option is going to have unlimited time, and be guaranteed. There is no way to enforce this, as many things can happen. Somebody tripping over the power cord or a forced termination of your program will prevent any option from giving you adequate time to handle things.
In general, putting your logic at the end of the Main routine is probably the most reasonable option, since that gives you complete freedom in handling your termination events. You have no time constraints there, and can have the processing take as much time as needed.
There are no guarantees that this will run, though, since a forceful termination of your program may bypass this entirely.
Based on the documentation, it looks like the default application domain (the one your Main method is probably running in) will not receive the DomainUnload event.
I don't know a built-in event that would do what you expect.
You could define your own custom event, have interested parties register with it, and fire off the event just before you return from Main().
I don't know how old this thread is, but I've had a similar problem whcih was a little tough for me to solve.
I had a WinForms application that was not firing any of the above forementioned events when a user logged out. Wraaping the Application.Run() in a try finally didn't work either.
Now to get around this you would have to using PInvoke into Win32 API's to achieve this. Well you did prior to .NET 2.0 anyways. Luckly MS introduced a new class called SystemEvents. With this class you can catch a SessionEnd event. This event allows you to cleanup when the OS want to terminate your app. There is no .NET time limit o this event it appears, although the OS will eventually kill your app if you take too long. This is a little more than 3 seconds, although 3 seconds should be plenty of time to cleanup.
Secondly my other problem was I wanted my worker thread to terminate the main thread once it was finished its work. With an Application.Run() this was hard to achieve. What I ended up doing was calling Application.Run() with a shared Application context. The thread is then able to call ApplicationContext.ThreadExit() to force the Application.Run to return. This seems to work quite nicely.
Hope this helps someone.
Regards
NozFX