I've been working on a DirectX application in C#, and I noticed that when I lock the workstation, the DirectX "Device" becomes lost. After looking up the information about what to do upon when a device is lost (and when a DeviceLostException is thrown by Device.Present), I re-wrote the code to reset the Device. This simply meant that I made a call to Device.Reset.
Calling Device.Reset recovered the Device. No problem. But when I lost the device a second time (for example, when the computer was locked, went to sleep, or activated a screen-saver), an exception was thrown by Device.Reset.
The exception was InvalidCallException, which (according to the documentation) means something went wrong with the call. So I assumed it was a problem with the arguments to the function. So instead of passing the same copy of PresentParams that I used to create the Device, I created a new instance of PresentParams (at first using the copy constructor, and later by re-creating without it) and passed that to Device.Reset.
Doesn't work. Device.Reset still dies with the InvalidCallException. Oh, and the message of the exception? "Error in application." Not helpful.
Can you point me in the direction of either a solution, or some documentation about how to get more debug information out of DirectX?
OK, I know how silly is seems to answer my own question, but I figured someone else might need this, eh?
The answer is: there were too many calls to the Dispose method of the VertexBuffers in the scene. The reason being that the internal Device reset-handlers were calling the Dispose method. And why was that happening? Because I had neglected to read the .NET DirectX SDK documentation regarding the Pool Enumeration, and was allocating the VertexBuffers using Pool.Default instead of Pool.Managed.
So obviously, after a few thousand badly done allocate-and-release cycles, something went wrong.
Oh, and how did I discover this? I attached a listener to VertexBuffer.Dispose which incremented a counter that I displayed on-screen. Imagine my suprise when I noticed this counter kept growing as I resized the window!
Related
I have an application (C# + WPF) that attempts to wrest control of the graphical interface of any process passed to it as an input and resize/reposition for my own purposes.
It does its job rather well, I think. Upon expected termination (the base class inherits from IDisposable) the "captured" process is released - its parent is set to the original, its windowstyle is reset, etc. etc.
In fact, on testing, I can capture, release, recapture, and so on, the same process as many times as I want with no issues.
However, upon unexpected termination (say another process forcefully kills it), the process never regains its graphical interface! I can tell its still running but I can never set that process back to its original state.
It almost seems like the process doesn't respond to window-based Win32 API calls that set specific window features anymore (for example, I can get information with GetParent, GetWindowThreadProcessId, etc but calling ShowWindow or related results in nothing).
Any suggestions on why this is happening? I'm guessing that since I set the parent of the process to my WPF application (which then unexpectedly closes) it causes some issue in trying to recover the initial interface?
This is why it's happening (or, at least, an indication of why I had so much difficulty finding the issue out on my own); can I recover from it? And, if so, how?
Edit -
IInspectable makes a good point in the comments, question adjusted to make better sense for this particular application.
It seems I've gotten my answer; so, for the sake of completeness I'll post what I've gotten here in case anyone else has a similar issue.
According to the information provided by IInspectable in here and here (with more context in the comments), it seems that what I'm trying to do here (assign a new parent cross-process) is essentially unsupported behavior.
My Solution:
Recovering (at least at the point that I'm talking about - i.e. unexpected crashes or exits) probably isn't feasible, as we've already gone off the end in undetermined/unknown behavior. So I've decided to go for the preventative route.
Our current project already makes use of the Nancy framework to communicate across servers/processes so I'm going to "refine" our shutdown procedure a bit for my portion of the program to allow it to exit more gracefully.
In the case of a truely unexpected termination, I'm still at a loss. I could just restart the processes (actually services with a console output, in our case, but w/e) but my application is just a GUI/Interface and isn't very important when compared to the function these processes serve. I may make some sort of semaphore file that indicates whether a successful shutdown occurs and branch my code off so that it indicates that the processes are no longer visible until the next time they're restarted.
I've got a strange behavior here:
I get a massive memory leak in production running a WPF application that runs on a DLOG-Terminal (Windows Embedded Standard SP1) that behaves perfectly fine if I run it localy on a normal desktop (Win7 prof.)
After many unsucessful attempts to find any problem I put one of those directly beside my monitor, installed the ANTs MemoryProfiler and did one hour test run simulating user operations on both the terminal and my development PC.
Result is, that due to some strange reasons the embedded system piles up a huge amount of WeakReference and EffectiveValueEntry[] Objects.
Here are are some pictures:
Development (PC):
And the terminal:
Just look at the class list...
Has anyone seen something like this before and are there known solutions to this?
Where can I get help?
(PS the terminals where installed with images prepared for .net4)
PPS: for the close-voter: I think the question is clear: how can I fix this.
You could argue if this is a IT/OS problem vs. a programming problem but I think if I post this in Server Fault it will get a off-topic close in no time...
UPDATE:
I was able to find a big portion of the problem - but it feels a bit like C++:
I use a ViewModel-like Items class for a WPF-List that provides (among others) a ICommand (RelayCommand-pattern). The Items where created on the fly in the getter of a ViewModel-Property for the view and it seems that the application/GC did never free those unused commands - or the subscribtions to their CanExecuteChanged - the memory profiler shows those as "held by a weak reference". I changed my code to reuse those item-viewmodels and Dispose/set to null every used properties in their Dispose and use this too as clean up - as I said: feels like "delete" in those old C++ days.
On top of this I use a forced GC.Collect every 30mins (yeah I know - you never should - but I got no other solution till now).
With this setup the applications runs for 6+ hours without problems so far but it don't feel right.
I cannot understand why those WeakReferences are not claimed as they are on my desktop machine...
Any thoughts on this? Please!
UPDATE:
I am still not able to pin down this problem but I see a strange behavior:
If I use PC-Anywhere to observe the operation of my software on one of the terminals the problem goes away!
Even after running 8hr. straight the software runs as it should - it will even free memory (I put a little memorycounter-display in the main-screen - let's say I connect to the terminal and see that memory is low - after waiting a few minutes the memory is reclaimed)
So I think Devin (one Answer below) has a lead in the right direction - something in the Remote-Control software unblocks the finalizer-thread or whatever is blocking the GC - be it the simulated keyboard/mouse or whatever.
Any thoughts on this?
We had a (somewhat) similar issue running my app on a tablet. The memory would be reclaimed when run on a desktop, but not when run on a tablet or some other device that used a PC Input panel. The problem is that the finalization queue was getting stuck. The COM object finalizer was waiting to run something on the main thread, which didn't have a message loop.
The solution was to find an adequate time to invoke Application.DoEvents(). We had a method that would be called intermittently and we invoke it with every 10th call. I don't know if this is the same issue you are having, but maybe it can shed some light.
EDIT: I do need to make it clear, in general, calling DoEvents() is a bad idea. It works in that case because there isn't any UI on that thread or anything else happening that those events can interfere with.
From the screenshots it is interesting to see that the LOH grows at the same time the used space does not grow much. The free space is growing a lot at the LOH which indicates memory fragmentation due to pinned objects. This looks like a stuck finalizer thread which does prevent the cleanup of managed objects. You should get a memory dump and check in which method the finalizer thread was stuck. You can do this quite easy with Windbg.
I have been trying to explaing this behavior in my c# optimization routine.
The program creates and solves large LPs using the cplex 12.2 API in a subroutine. For the purpose of hunting this bug, I changed it so that it solves the same problem repeatedly. After solving, I
call cplex.End() on the instance, and the cplex instance goes out of scope, so the memory will be deallocated.
The second time I create the model and call cplex.Solve(), it does not solve the model. It gives the error: "CPLEX error 1217: No Solution Exists", which is not so credible since it solved the same problem the first time. (memory requirements at the moment of the crash were just 1.3 GIG)
Now, if I force a garbage collect between the two solves, cplex solves the model the second time as it did the first time.
Can anyone explain this behavior to me? And the way to properly fix it?
We recently started seeing this exception pop up during initialization:
System.Net.NetworkInformation.NetworkInformationException: An operation was attempted on something that is not a socket
at System.Net.NetworkInformation.NetworkChange.AddressChangeListener.StartHelper(NetworkAddressChangedEventHandler caller, Boolean captureContext, StartIPOptions startIPOptions)
at System.Net.NetworkInformation.NetworkChange.AvailabilityChangeListener.Start(NetworkAvailabilityChangedEventHandler caller)
at System.Net.NetworkInformation.NetworkChange.add_NetworkAvailabilityChanged(NetworkAvailabilityChangedEventHandler value)
(snip)
This is an app that runs on a number of client machines. This subscription is one of the first things we do during initialization, and the code around it hasn't changed recently. Since the stack trace is several layers below a subscription call (and thus not directly influenced by any parameters we send), I suspect that something has changed out from underneath us, but I haven't been able to find enough information on this exception to know where to start looking.
Any ideas would be greatly appreciated!
Ultimately this turned out to be associated with our use of the Komodia Redirector (our install process was not happening cleanly which can lead to some strange behavior at the network LSP layer). Once we got the install to work properly, this issue went away (though we later ditched Komodia for unrelated reasons).
I've been experiencing a high degree of flicker and UI lag in a small application I've developed to test a component that I've written for one of our applications. Because the flicker and lag was taking place during idle time (when there should--seriously--be nothing going on), I decided to do some investigating. I noticed a few threads in the Threads window that I wasn't aware of (not entirely unexpected), but what caught my eye was one of the threads was set to Highest priority. This thread exists at the time Main() is called, even before any of my code executes. I've discovered that this thread appears to be present in every .NET application I write, even console applications.
Being the daring soul that I am, I decided to freeze the thread and see what happened. The flickering did indeed stop, but I experienced some oddness when it came to doing database interaction (I'm using SQL CE 3.5 SP1). My thought was that this might be the thread that the database is actually running on, but considering it's started at the time the application loads (before any references to the DB) and is present in other, non-database applications, I'm inclined to believe this isn't the case.
Because this thread (like a few others) shows up with no data in the Location column and no Call Stack listed if I switch to it in the debugger while paused, I tried matching the StartAddress property through GetCurrentProcess().Threads for the corresponding thread, but it falls outside all of the currently loaded modules address ranges.
Does anyone have any idea what this thread is, or how I might find out?
Edit
After doing some digging, it looks like the StartAddress is in kernel32.dll (based upon nearby memory contents). This leads me to think that this is just the standard system function used to start the thread, according to this page, which basically puts me back at square one as far as determining where this thread actually comes from. This is further confirmed by the fact that ALL of the threads in this list have the same value for StartAddress, leading me to ask exactly what the purpose is...?
Edit 2
Process Explorer let me to an actually meaningful start address. It looks like it's mscorwks.dll!CreateApplicationContext+0xbbef. This dll is in %WINDOWS%\Microsoft.NET\Framework\v2.0.50, so it looks like it's clearly a runtime assembly. I'm still not sure why
it's Highest priority
it appears to be causing hiccups in my application
You could try using Sysinternals. Process Explorer let's you dig in pretty deep. Right click on the Process to access Properties. Then "Threads" tab. In there, you can see the thread's stack and module.
EDIT:
After asking around some, it seems that your "Highest" priority thread is the Finalizer thread that runs due to a garbage collection. I still don't have a good reason as to why it would constantly keep running. Maybe you have some funky object lifetime behavior going on in your process?
I'm not sure what this is, but if you turn on unmanaged debugging, and set up Visual Studio with the Windows symbol server, you might get some more clues.
Might be the Garbage Collector thread. I noticed it too when I was once investigating a finalizer-related bug. Perhaps your system memory is low and the GC is trying to collect all the time? This was the case in the previously mentioned bug too. I couldn't reproduce it on my machine, but a co-worker of mine had a machine with less RAM where it would reappear like clockwork.