Gorchestopher H
Gorchestopher H

Reputation: 1161

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.

Upvotes: 5

Views: 378

Answers (3)

dlev
dlev

Reputation: 48596

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.

Upvotes: 1

Anders Abel
Anders Abel

Reputation: 69280

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.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1502806

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.

Upvotes: 9

Related Questions