How does Ninject 3 affect object lifetime? - c#

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?

Related

My Windows Forms Application is still running as task after closing

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

What isn't available to me before calling Application.Run() in a standard WinForms application?

I want to do some initialization of various things at runtime of my WinForms application. I'm looking specifically at the Program.cs file that every WinForm application has. In it, I see:
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmMain());
}
I know that this is what starts up the application and creates the initial form (in my case, an instance of frmMain).
Can I not just put my initialization code before Application.Run()? The initialization I need to do is to check a few registry entries, create them if necessary, and connect to a database. Will any feature not be available to my instantiation code if I put it before Application.Run()?
Application.Run() starts message loop for your main thread. SO before that line of code you can do anything except what is dependent on windows messages (click, keyup, ...)
A Windows Forms application starts when the Main method is called. You can implement initialization procedures on the Main function. However, to initialize a Windows Forms application fully and start it routing Windows Forms events, you need to invoke Application.Run.
Read about Application
Yes, no problem, the code in Main() is boilerplate but not cast in stone.
Do keep in mind that any code you run before calling Application.Run() will delay the startup of your user interface. Once that goes over a second or two, give or take, you might want to consider displaying a splash screen so that the user gets some visual feedback that your program got started. Well supported by the .NET framework, check this answer.
One important thing you don't have available before Run is a valid SynchronizationContext.Current. So if you use any kind of event-based asynchronous pattern components, they'll seem to work just fine, but will fire their events on a thread pool thread instead of the GUI thread.
Because of this, any asynchronous startup code that queues completion events to the GUI should be started from an event, not before Run.
As long as you don't need to access anything declared in frmMain you should be OK.
However the MSDN states:
Begins running a standard application message loop on the current thread.
so you won't have access to the message loop.
There is another overload Application.Run(ApplicationContext) that will let you execute code before your form is displayed - this appears to be the way to go.
The example code on this page does some initialisation before showing two forms, so you should be OK with your model.

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.

App doesn't exit when main window is closed

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.

Possible to "spin off" several GUI threads? (Not halting the system at Application.Run)

My Goal
I would like to have a main processing thread (non GUI), and be able to spin off GUIs in their own background threads as needed, and having my main non GUI thread keep working. Put another way, I want my main non GUI-thread to be the owner of the GUI-thread and not vice versa. I'm not sure this is even possible with Windows Forms(?)
Background
I have a component based system in which a controller dynamically load assemblies and instantiates and run classes implementing a common IComponent interface with a single method DoStuff().
Which components that gets loaded is configured via a xml configuration file and by adding new assemblies containing different implementations of IComponent. The components provides utility functions to the main application. While the main program is doing it's thing, e.g. controlling a nuclear plant, the components might be performing utility tasks (in their own threads), e.g. cleaning the database, sending emails, printing funny jokes on the printer, what have you. What I would like, is to have one of these components be able to display a GUI, e.g. with status information for the said email sending component.
The lifetime of the complete system looks like this
Application starts.
Check configuration file for components to load. Load them.
For each component, run DoStuff() to initialize it and make it live its own life in their own threads.
Continue to do main application-thingy king of work, forever.
I have not yet been able to successfully perform point 3 if the component fires up a GUI in DoStuff(). It simply just halts until the GUI is closed. And not until the GUI is closed does the program progress to point 4.
It would be great if these components were allowed to start up their own Windows Forms GUIs.
Problem
When a component tries to fire up a GUI in DoStuff() (the exact line of code is when the component runs Application.Run(theForm)), the component and hence our system "hangs" at the Application.Run() line until the GUI is closed. Well, the just fired up GUI works fine, as expected.
Example of components. One hasn't nothing to do with GUI, whilst the second fires up a cute windows with pink fluffy bunnies in them.
public class MyComponent1: IComponent
{
public string DoStuff(...) { // write something to the database }
}
public class MyComponent2: IComponent
{
public void DoStuff()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form());
// I want the thread to immediately return after the GUI
// is fired up, so that my main thread can continue to work.
}
}
I have tried this with no luck. Even when I try to fire up the GUI in it's own thread, the execution halts until the GUI as closed.
public void DoStuff()
{
new Thread(ThreadedInitialize).Start()
}
private void ThreadedInitialize()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form());
}
Is it possible to spin off a GUI and return after Application.Run()?
Application.Run method displays one (or more) forms and initiates the standard message loop which runs until all the forms are closed. You cannot force a return from that method except by closing all your forms or forcing an application shutdown.
You can, however, pass an ApplicationContext (instad of a new Form()) to Application.Run method and ApplicationContext can be used to launch several forms at once. Your application will only end when all of those are closed. See here: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.run.aspx
Also, any forms that you Show non-modally will continue to run alongside your main form, which will enable you to have more than one windows that do not block each other. I believe this is actually what you are trying to accomplish.
I'm sure this is possible if you hack at it hard enough, but I'd suggest it is not a good idea.
'Windows' (that you see on the screen) are highly coupled to processes. That is, each process which displays any GUI is expected to have a Message Loop, which processes all of the messages which are involved with creating and managing windows (things like 'clicked the button', 'closed the app', 'redraw the screen' and so on.
Because of this, it is more or less assumed that if you have any message loop, it must be available for the lifetime of your process. For example windows might send you a 'quit' message, and you need to have a message loop available to handle that, even if you've got nothing on the screen.
Your best bet is do it like this:
Make a fake form which is never shown which is your 'main app'
Start up
Call Application.Run and pass in this fake form.
Do your work in another thread, and fire events at the main thread when you need to do Gui stuff.
I'm not sure if this is right, however I remember running window forms from a console application by just newing the form and calling newForm.Show() on it, if your components use that instead of Application.Run() then the new form shouldn't block.
Of course the component will be responsible for maintaining a reference to the forms it creates

Categories