My project requires a restart if the user changes the settings before the settings will take effect. I have created a DialogResult prompt that asks the user if they want to restart the program. I call a MessageBox which returns a Yes/No and if you click "no" it behaves appropriately and doesn't close the program. If you choose "yes" the application closes... and that's it, no restart. I do have some close validation going on which I've read can cause issues, but I was under the impression that was issues with the program closing, not restarting? What might cause the application to not restart? Is there more to the method than just calling it that I need to be doing?
I attempt to restart the application calling the method:
Application.Restart();
As to whether I use threads, I am not consciously using threads cause I don't really know what that means to be honest.
Generally when you use this method, your app will restart.
It is ordinarily a routine action, but I saw in your question that you have some validation logic running when the app is closed. Thus, I'm about 90% sure that this error occurred because some of those validations failed. Post the validation code, and someone can help you debug the problem.
So thanks to the link from above I found a recommendation on a different thread that was a great workaround to simply using the Application.Restart() method.
System.Diagnostics.Process.Start(Application.ExecutablePath);
Application.Exit();
It allows my program to restart very effectively in spite of my closing validation.
This would probably still be an issue if I did any closing validation related to the Application.Exit call.
Related
What is the best way to kill an application instance?
I am aware of these three methods:
Application.Exit()
Environment.Exit(0)
Process.GetCurrentProcess().Kill()
Can anyone tell me which is better or when using each of the above would be appropriate?
guidelines from c# faq:
System.Windows.Forms.Application.Exit() - Informs all message pumps that they must terminate, and then closes all application windows after the messages have been processed. This method stops all running message loops on all threads and closes all windows of the application. This method does not force the application to exit. The Exit method is typically called from within a message loop, and forces Run to return. To exit a message loop for the current thread only, call ExitThread. This is the call to use if you are running a WinForms application. As a general guideline, use this call if you have called System.Windows.Forms.Application.Run.
System.Environment.Exit(exitCode) - Terminates this process and gives the underlying operating system the specified exit code. This call requires that you have SecurityPermissionFlag.UnmanagedCode permissions. If you do not, a SecurityException error occurs. This is the call to use if you are running a console application.
Killing the process is likely not recommended.
If this is a Windows Forms application, use Application.Exit(). That will close the program nicely.
Just a quick answer, I would always use the "Exit" option when it will work. It is a much cleaner way to do it.
To "Kill" a process means exactly that, and therefore the program does not get to do any cleanup work it might want to do (like saving configuration, saving other files, etc...). Unless you know what the process is and that it does not have any "cleanup" to do, and even then, it's just cleaner to use "Exit."
There does not appear to be any difference between the two "Exit" options you mention, I would wager that the first is simply implicitly passing the zero value.
foreach (Process proc in Process.GetProcessesByName("WindowsFormsApplication1.vshost"))
{
proc.Kill();
}
I have an unhandled exception handler. It shows a nice GUI and allows users to send an error report. Users can even leave their name and phone number and things, and our support department calls them back. Works well, looks good, makes customers less angry. In theory, anyway.
The problem is that my application uses background threads, and the threads don't seem to care if an exception was thrown on, say, the GUI thread (which makes sense), and just continue their work. That eventually results in a WER dialog poping up if the user lets my custom exception handler window stay open long enough, making it look like the error handler itself crashed.
I don't have access to the thread objects in the scope of the exception handler, so I can't suspend them. Making the thread objects globally accessible is not a solution either. My workaround for now is to use something like Globals.Crashed = true; in my exception handler, and to have my thread methods check that property at every loop iteration. Not perfect, but it minimizes the damage.
Does anyone know a less-hacky method? Is my approach wrong? Do I have to do it like WER does and launch an external program that suspends the main program and shows the error UI?
If you have an unhandled, unknown exception, you can assume that ANYTHING has happend and that your program might fail to do even the most simple thing. Consider e.g. the case that it has consumed all available memory - then you won't be able to send the error report either, because it probably requires memory to be allocated.
A good approach is to write a separate small application that just does the error reporting. That application can pick up the details to report from a file. That way your unknown exception handler would:
Dump the info to a file in the temp directory.
Start the error reporting app with the file name as an argument.
Terminate the failing process, before it does something stupid.
The temp file should be removed by the error reporting app.
You could track all your threads in a global Collection object, so that when your handler executes, it could simply iterate through the collection object and abort the threads there.
Take a look at the code in this question, Suspend Process in C#, you'll need to tweak it so as to not suspend your GUI thread and any that aren't background ones you've started, but it should do the trick.
The better option, however, is to try and launch your error report GUI as a separate process, passing any required information to it, and then kill the original process from your unhandled exception handler, rather than allowing anything to run in a potentially corrupt state.
I have a Windows Mobile program that accesses an attached device through a third-party DLL. Each call to the device can take an unknown length of time, so each call includes a timeout property. If the call takes longer than the specified timeout to return, the DLL instead throws an exception which my app catches with no problem.
The problem that I have is with closing the application. If my application has made a call to the DLL and is waiting for the timeout to occur, and I then close the application before the timeout occurs, my application locks up and requires the PDA to be rebooted.
I can ensure that the application waits for the timeout before closing, under normal conditions. However, I am trying to use AppDomain.CurrentDomain.UnhandledException to catch any unhandled exceptions in the program and use the event to wait for this pending timeout to occur so the program can be closed finally.
My problem is that this event doesn't seem to stick around long enough. If I put a MessageBox.Show("unhandled exception"); line in the event, and then throw a new unhandled exception from my application's main form, I see the message box for a split second but then it disappears without my having clicked the OK button.
The documentation I've found on this event suggests that by the time it's called the application is fully committed to closing and the closing can't be stopped, but I didn't think it meant that the event method itself won't finish. What gives (I guess that's the question)?
Update: In full windows (Vista) this works as expected, but only if I use the Application.ThreadException event, which doesn't exist in .Net CF 2.0.
I came across this problem as well. This is a known issue in .NET CF (v2.0), but I also had it while using v3.5 (although the situations in which it occurs are more specific). You can find the (old and still active) bug report here.
Calling MessageBox.Show() causes it to close immediately, but in my case there were two workarounds:
1) Call the MessageBox.Show() a second time. It then does block until closed by the user. You can check the first MessageBox.Show() closed prematurely by checking the DialogResult. I don't remember which result it returned exactly when it failed, I remember it giving a non-default result.
2) Create a custom Form and call ShowDialog() on that. It worked for me, but others have reported it doesn't work. You could also call Show() and make it blocking yourself (don't forget to call Application.DoEvents() so it keeps processing events).
I have a console application written in C#/.NET that I want to run from a script (nant). If an exception occurs in the console application, I would like nant to continue, but in Windows Vista there is a popup that searches for solutions and asks for debug etc.
I would like to avoid the popup with "program stopped working" when an exception happens in the console application. How can I control this from C#/.NET?
(A similar question addresses the issue for the C language, but I would like a solution for C#/.NET.)
(To clarify: I would like the exception to be passed to nant, but without the popup.)
The JIT debugger popup occurs when there's an unhandled exception. That is, an exception tunnels all the way up the stack to the root of any thread in the runtime.
To avoid this, you can handle the AppDomain.CurrentDomain.UnhandledException event and just call Environment.Exit(1) to exit gracefully.
This will handle all exceptions on all threads within your AppDomain. Unless you're doing anything special, your app probably only has one AppDomain, so putting this in your public static void Main method should suffice:
AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
{
Console.Error.WriteLine("Unhandled exception: " + args.ExceptionObject);
Environment.Exit(1);
};
You should probably use the NAnt logger to write out the error in this case too (can't recall the API for this offhand though.)
You can also disable JIT debugging on the machine. I would only recommend this in certain circumstances such as for a dedicated build server.
Under Windows Vista you can disable this dialog for your programms.
Disable the "Problem Reports and Solutions feature". You find it under Control Panel-->Problem Reports and Solutions-->Change Settings-->Advanced Settings-->Turn off for my programs, problem reporting
Just catch the exception and log/ignore it.
The popup appears due to an unhandled exception. To avoid that make sure your main method captures all exceptions and turn them into some other useful piece of info you can pick up. Just ignoring the exception is not recommended.
Btw remember that exceptions are per thread, so if your application spawns threads or uses thread pool threads, you need a handler for these too.
Usually this only happens when your app doesnt handle an exception. If you wrap your whole console app in a try/catch bblock, and just pass back a fail code, then you will avoid this.
Sometimes, a windows application will stop working if you are using a System.Timers.Timer.
To fix this, change System.Timers.Timer by System.Windows.Forms.Timer
Greetings
I keep having this problem, solving it, and then when I implement new code it comes back again. It's driving me crazy!
What I finally found was that if you instantiate a Window of any kind, even if you never call Show() or ShowDialog(), when you close your application, it will not terminate. So now I make sure to call Close() when appropriate, and the problem hasn't ever come back with all of the Windows that I've created.
I've implemented more new features that don't create windows (as far as I can tell!), yet now my app will not terminate again. Hitting pause in the VS IDE is useless, I think, because the threads don't have any context so I can't figure out what code caused the hanging.
Normally, I would expect that a thread executing in the background that hasn't exited (and wasn't set as a Background thread) would cause this behavior, but I am not creating any threads at this point.
Can anyone recommend a good tool (free or license required) that will help me quickly resolve these sorts of stupid problems? For now, I'm going to go back, comment out a ton of the new code, and then uncomment line by line until the problem reappears. Brute force is how I typically end up fixing these sorts of things, and would really appreciate a tool to make my life easier. :)
It sounds like you may be having other issues with background threads that the other answers are addressing but with regard to WPF Windows, have you tried changing the ShutdownMode of your App class? You can also try forcing the app to quit by calling Shutdown explicitly:
Application.Current.Shutdown();
You might get more information if you attached using both managed and unmanaged code. In Visual Studio 2008, you can change the mode in the Attach to Process form. Press the "Select..." button and specify debugging for both "Managed" and "Native".
(Before you do this, make sure your symbol path is setup. Go to Tools/Options, Debugging, Symbols. Enter http://msdl.microsoft.com/download/symbols in the list of symbol file locations. Cache the symbols locally in some directory.)
When you attach in both managed and unmanaged modes, you should get a larger call stack. I recommend right-clicking in the Call Stack debug window and choosing "Include Calls To/From Other Threads".
If your main thread shows System.Windows.Forms.Application.Run or ThreadContext.RunMessageLoop, then your UI thread's message pump is alive and still pumping messages. If, for some reason, it is transitioning to another thread, then it can't exit until it's done.
You can also see the full stack traces of the rest of the managed and unmanaged threads. You might want to look for a garbage collector thread and see what it's doing. Look for one that is has a stack with "GCHeap::FinalizerThreadStart" in it. That might be doing something.
There may also be a GID+ thread that's busy trying to do work.
I don't mean to over-simplify things, but have you tried setting the owner of the dialog window to the MainWindow? This will force the dialog window to close when the MainWindow is closed. In other words, it would look like this:
dialog.Owner = Window.GetWindow(this);
// Or...
dialog.Owner = Application.Current.MainWindow;
This may not be an option for you, but I just wanted to throw it out there since your post didn't mention you didn't want to set the window's owner.
While it may not help in your particular case, Process Explorer is an excellent tool for looking inside running processes and seeing how many threads etc. there are.