Destroying unmanaged objects in C# - c#

I'm working on an application just now which uses a bunch of external DLLs to make a connection to a server somewhere. Oddly, the exposed methods for these DLLs allow a connection but NOT a disconnection or close. These libraries work fine unless you make a lot of subsequent calls to the server in one chunk, so what I decided to do was disconnect and reconnect after X amount of calls.
However, herein lies the issue. I cannot disconnect because no disconnect method is given. SO my question is, how can I totally kill this unmanaged object so I can recreate it again?

If you're using unmanaged resources in C# you should have your classes that use and interact with the unmanaged resources implementing IDisposable and creating and destroying them with using blocks.
If you can't disconnect, depending on exactly what you're interfacing sometimes setting the variable containing your unmanaged resource to null will clear some of it up. Really though, there's not a great deal you can do without proper disconnect/dispose methods.

You could manually close the underlying connection to the server. I cant help you any more with how to do that without knowing more about the service your consuming (HTTP TCP ect?). You could put a trace (like wireshark) up and see what's being transferred.
Bottom line though is their software is broken. Can you not contact the vendor?

The best solution I could find for this, was to run each call to the external DLL in it's own thread, which was eventually killed when the thread ended. This was the only resolution that worked, given I had no access to updated DLLs.

Related

How to drop tcp / udp connection using code?

I am currently using .net core and would like to be able to drop some tcp and/or udp connections that are open on the host machine.
I have already built all the logic for checking the open connections and I am now just needing to find some resource that will help me drop the connection on the machine.
With windows I can use a third party program passing some parameters during initialization. However I need it to work on a linux machine.
Windows Solution = http://www.nirsoft.net/utils/cports.html
Network connections are a very common example of unmanaged Resources, that need to be disposed off. A big reason we Dipose of SQL Connections, is because of the underlying network connection.
When dealing with disposeable classes my advise is: "Create. Use. Dispose. All in the same piece of code, ideally using a using statement."
Note that with Networking you usually have to apply some form of Multitasking. Async/Await is the more modern approach, but a seperate thread can also be used. That prevents the UI thread from being blocked, while still making sure the using is not split up logically - and thus stays reliable.

How to approach removing needless instantiation when calling native method from WebAPI

I have a dotnet core WebAPI web server that needs to execute a native method written in Win32 C++. The problem is, each time this method is called it needs to instantiate a bunch of things before it can do what it needs to do, this adds delays to the request. (It's currently using DLLImport to access the C++ method in the compiled DLL).
What I would like to do is have some sort of long running process start when the server starts, which will handle the initialization once, then have my WebAPI service call a method inside this process that executes the code that I actually need to run immediately, without the need to initialize its dependencies each time. Since this is a web server, the process will need to be able to handle multiple requests at once.
What is the recommended approach for this? I have full access to the C++ code and the WebAPI server code so I'm free to do whatever needs to be done to accomplish this.
You may set-up some IPC infrastructure between the two.
One way to do it would be to make your DLL COM compatible. I.e having the DLL be a COM server to some COM class. The server process would then 'CreateInstance' a class, which will automatically launch your native process. A call would then just be a normal function call, COM will handle the RPC.
Another simpler way will be using a named memory-mapped file. Both processes will open a handle to this, there you can store a queue or some data structure. The server process will push while the native process will pop. You can use windows events to synchronize this. You can write this yourself or use something like boost::interprocess for the C++ part. I assume there may be other IPC libraries you may find for this.
You can also use a Pipe, I know C# has some easy ways to handle windows pipes. Pipes do not need synchronization but to efficiently handle a number of such requests you may need a number of threads on the native process to read from the pipe.
Personally i'd go with using COM if that is possible. As it will hide for you the low-level IPC stuff that may be a pit-fall. It is a bit longer to set-up though.

Async Socket High Memory Usage and Possible Leak

I have a server application rewrite underway and am puzzled by the memory usage of the application. The earlier version was written with TcpListener while the new one is plain old Socket. This is mostly for performance and stability reasons which are secondary to this question and even this issue.
As mentioned, everything is heavily async'd with AcceptAsync, SendAsync, and ReceiveAsync. On top of that, I use ThreadPool.QueueUserWorkItem for utility tasks such as the initial kick-off for AcceptAsync and keeping the next AcceptAsync queued, the call after processing to write back to the Socket, and the call cleaning up disconnected clients. Further, there are a series of events that I fire with BeginInvoke and EndInvoke.
The detection for those disconnects as well as the main driver for data availability are handled by a custom class that I call AvailabilityNotifier that peaks on a ReceiveAsync as well as detecting for SocketAsyncEventArgs.BytesTransferred being zero which fires a Disconnect event.
The throughput of the application is good, and there's almost zero (relatively speaking) lock contention thanks to a healthy usage of System.Collections.Concurrent objects. However, it clings to memory like a predator clinging to a kill.
I've debugged to verify my internal collections are getting cleared, the client sockets are being shutdown and disposed of, and utilizing a buffer pool instead of creating new buffers for each read. Running a test application that ultimately performs 1,000 connections (100 concurrent) and sends/receives 100,000 messages bloats the server process memory to around 800 MB and it never goes down even after Windows clears any TIME_WAITs that might have happened. I know for sure the diposal code is firing thanks to a ton of ObjectDisposedException and null exception catch blocks that you can see in the linked github below.
I say all that without quoted code as it's quite long for a post here so here's a github: https://github.com/hoagsie/TcpServer. The Program.cs and ClientProgram.cs is provided as well if you'd want to run it yourself but the main action is in NetworkServer.cs and AvailabilityNotifier.cs. The sample server I have running also has a WCF service it talks to but is just the standard WCF project with literally no modifications. I just needed it to match a sample scenario.
I'm also not sure if it matters on some level, but I do build this in x64 mode rather than AnyCPU/x86. This is mostly for resource consumption opportunity on the target server it will be going on, but I haven't noticed a difference in behavior with regard to this issue in either x86 or x64.
EDIT:
A coworker pointed out the Snapshot tool in Visual Studio. I had never seen this before and it displayed things differently from what I had been using, which was dotTrace. It pointed to a ton of allocations around the SocketAsyncEventArgs object which makes sense, but they kept building and building. I looked at its member list again and discovered it had a Dispose method. My issue has gone away. I didn't realize that was an IDisposable object.
A coworker pointed out the Snapshot tool in Visual Studio. I had never seen this before and it displayed things differently from what I had been using, which was dotTrace. It pointed to a ton of allocations around the SocketAsyncEventArgs object which makes sense, but they kept building and building. I looked at its member list again and discovered it had a Dispose method. My issue has gone away. I didn't realize that was an IDisposable object.

How to unload unsued COM objects/libraries after a complete restart?

Here is the thing. I'm connecting via COM to some devices at KNX/EIB. But sometimes - and I want to be ready for worst-case anyways - my application crashes leaving all objects and libraries exposed somewhere, somehow. I noticed when I restart the app I have trouble to get a connection again. I get an error for a connection procedure that is actually working well normally. Sometimes this connect procedure is working sometimes it is not, randomly. That is bad! After some time (several minutes) it seems to work again after a series of complete fails. But I think I see a pattern now. It doesn't work after a crash with no clean disconnect. My guess is there are objects that hold a connection to the device that us why I can't get a new connection. This is why I ask this question.
Question:
How do I unload those unused objects to kill undead connections?
How do I make Windows to check for unused libraries to be unloaded?
I just want to tell Windows, "I messed up badly and I need to continue my work. Please clean up my mess for me, so I can start fresh! Do I deserve a 2nd chance?"
Edit:
The scenario is the app has crashed and closed. I have no references to anything anymore. No finally clause or anything. The app can only be started again. What can I do to clean up the mess that has been made before, programmatically?
Edit 2:
Hans gave me the hint of killing the responsible server. So for now I solve that with calling taskkill on startup (at least as long I'm in dev). And it works!
C:\Windows\System32\taskkill.exe /F /IM Falcon.exe
This is the failure mode of an out-of-process COM server. If the client program crashes to the desktop without releasing the interface pointers then the server is completely unaware that the client isn't around anymore. And tends to get balky when you try to reconnect, many servers just permit one client.
By far the most common way that programmers induce this failure mode is by using a debugger. They'll click the Red Button or use the Stop Debugging command. Bam, no cleanup of course.
COM garbage-collects unused servers automatically. But that isn't particularly fast, takes an easy 10 minutes before it decides it needs to step in. And doesn't always work for every server, Office programs notoriously don't get cleaned-up for example.
Not much you can do about this when your app keels over in regular usage. Otherwise the kind of problem that killed middle-ware. Still, having such a mishap in a C# program is pretty unusual, the CLR releases interface pointers at program termination even when the app crashed with an exception. You'd have to have the very nasty kind of mishaps to bypass this, critical exceptions like ExecutionEngineException or the one this site is named after.
Don't focus too much on the Stop Debugging induced failures, it is normal and using Task Manager to kill the server is expected and required. Otherwise just be sure to get the nasty bugs out of your code and you won't have a problem. If you need more help then be sure to contact the owner of the server, be sure to have a small repro project available that demonstrates the issue.

What do I do When Dispose Method Fails?

Well, here I am again with another frustrating question.
I need to end my main process and restart it, but I can't just end the application gracefully...
I am using a C# application in conjunction with proprietary (not to me) data capture hardware, so right there it's already complicated.
There is a scenario when my software is happily running, collecting its data as it should, when the hardware I'm interfacing with suddenly loses power and the connection to my application. My application eventually figures this out and I just need to dispose of my old connection, and make a new one to connect to my hardware again. Wrong...
Of course, the .Dispose() method on my object (the interface object with the hardware), that terminates the connection does nothing, and actually just locks in place forever when I try to run it. Apparently there is some kind of communication that never times out on the dispose method that requires the device to be connected when the disconnection happens. I didn't write the method, so I don't really know.
Finally, here's my question. The only way to get my application up and running again is to close it and reopen it. Of course, I can't actually close it nicely because I can't run the Dispose method. I am forced to end it's process via task-manager. Yes, the process, not just the application. If I just close it, the process will stay alive forever, I have no choice.
I need to find a way to automate this process assassination so my users can actually use it, but what can I do? I know process termination is taboo, but what options do I have?
I'd love to use Application.Restart(), but that doesn't work at all, my form doesn't even close, it just locks. Is there a way to axe the process just before telling itself to launch again? Maybe I can do this with a batch file or something? Application.Exit at least takes the form off the screen.
As of now, I'm killing it from Task Manager, or my users are killing it by popping the breaker on the PC. Considerably more harsh than anything software-wise.
Have you considered isolating the problematic component in another process? I know it sounds complicated, but if you create another "application" which solely exists as a conduit to your device, you can make your main application just start a new one of those if the old one becomes unresponsive. It can nuke the old one, start a new one, and be "clean" again.
It does mean all kinds of inter-process communication of course, but the general idea of isolating something flaky is often a useful one.
Assuming that it is Dispose() that is the problem and that there is a proper IDisposable pattern implementation where the finalizer calls Dispose() I think that a solution might be to call GC.SupressFinalize(objWithFailingDispose) to prevent Dispose from being called at all.
It is ugly, but I might work.
This question should probably be titled "What do I do when I'm dealing with a Dispose() method I can't change, and has been written without considering a very real and very troubling real-world scenario?" And my suggestion would be to write a better one!
The simplest approach would be to create a wrapper for the object that will be disposed, and then calling GC.SuppressFinalize(internalConnectionObject); if you've detected that the connection has dropped. That way, if it's not responsive, it won't get stuck, but if it's there, it will be disposed properly. Isolation is your friend when you have troublesome components.

Categories

Resources