goopyJava
asked on
How to Handle Third Party Exception in During Exit
All,
I am a contractor working building a large commercial piece of software. Because of limited time and resources I have to rely on third parties from time to time to get things built faster, better or just simply more cheaply than I can do myself. Because of this exact reason I am using a third party TWAIN interface, that was written in .NET.
In this particular piece of software it came with a "trial license" and everything seemed to be working fine. I purchased the software and again, things seemed to be working fine until I logged on to the machine as a non-administrator and my software crashed after the last line of MY code has run. Piecing things down a bit further (using reflector) I found out that the license provider for this component is relies on an internal static LicenseProvider variable which isn't finalized till after my application closes. Interestingly, this variable (on dispose, of course) tries to delete a file on the hard drive which it doesn't have access to and so it crashes (a license file that was stupidly created by the same provider earlier).
My question is - without throwing out a third party component that mostly works is their any way to prevent finalize routines from being called or to catch exceptions that happen while the GC is finalizing objects? I have search google but the most suggestions require access to the code which I don't have. Hopefully someone has an idea to try.
Personally, my best idea to date is loading the third party in its own app domain and unloading the domain once I am finished with it but I don't really know much of what that looks like in code. Any help is appreciated.
Thanks!
I am a contractor working building a large commercial piece of software. Because of limited time and resources I have to rely on third parties from time to time to get things built faster, better or just simply more cheaply than I can do myself. Because of this exact reason I am using a third party TWAIN interface, that was written in .NET.
In this particular piece of software it came with a "trial license" and everything seemed to be working fine. I purchased the software and again, things seemed to be working fine until I logged on to the machine as a non-administrator and my software crashed after the last line of MY code has run. Piecing things down a bit further (using reflector) I found out that the license provider for this component is relies on an internal static LicenseProvider variable which isn't finalized till after my application closes. Interestingly, this variable (on dispose, of course) tries to delete a file on the hard drive which it doesn't have access to and so it crashes (a license file that was stupidly created by the same provider earlier).
My question is - without throwing out a third party component that mostly works is their any way to prevent finalize routines from being called or to catch exceptions that happen while the GC is finalizing objects? I have search google but the most suggestions require access to the code which I don't have. Hopefully someone has an idea to try.
Personally, my best idea to date is loading the third party in its own app domain and unloading the domain once I am finished with it but I don't really know much of what that looks like in code. Any help is appreciated.
Thanks!
ASKER
Do you believe that Finalize exceptions can be caught when AppDomain.Unload is called?
Like I said, probably won't solve your entire problem, but that's how you go about creating Application Domains. What is the exact type of exception thrown?
ASKER
Right after I close the program I get a screen that pops up and says "<program name> has encountered an error and needs to close". Clicking to see the error report isn't very helpful.
Well, since I already closed the program this really just annoys me (as it will users). Tracking this down wasn't that hard - some debugging quickly showed it was after the main thread finished running. Presumably something with the GC. I just thought about things I had done recently and remembered the third party TWAIN app. Taking this out fixed the issue, but I need the TWAIN stuff in the software...
I would try the app domain stuff but reflection takes so long to program. Do you have any thoughts on how to load a dll dynamically but build like its static? Or possibly there is another way to do all this I haven't thought up.
Thanks again!
Well, since I already closed the program this really just annoys me (as it will users). Tracking this down wasn't that hard - some debugging quickly showed it was after the main thread finished running. Presumably something with the GC. I just thought about things I had done recently and remembered the third party TWAIN app. Taking this out fixed the issue, but I need the TWAIN stuff in the software...
I would try the app domain stuff but reflection takes so long to program. Do you have any thoughts on how to load a dll dynamically but build like its static? Or possibly there is another way to do all this I haven't thought up.
Thanks again!
Yeah, that's quite a pickle... Unfortunately, I'm not very good at adapting to others' programs--I prefer to use my own. My last suggestion entails the most work out of them all--program our own version. I've found that Security issues are truly the biggest pain in the ass of them all, being extrememly difficult to work around, if there even is a work-around at all.
My last suggestion is pretty lame: get in contact with the creators of the program, and see what they think, or ask if they would give you access to the code. From there, you can hack things up a bit and make it a bit more friendly, maybe catch the exception, or prevent the code that's throwing it from running in the first place.
Sorry for the delay--in the process of moving households.
Hoped I helped at least a bit,
Nate
My last suggestion is pretty lame: get in contact with the creators of the program, and see what they think, or ask if they would give you access to the code. From there, you can hack things up a bit and make it a bit more friendly, maybe catch the exception, or prevent the code that's throwing it from running in the first place.
Sorry for the delay--in the process of moving households.
Hoped I helped at least a bit,
Nate
ASKER
I appreciate the help. Actually your suggestion was right in line for what I was already trying. At the same time that I posted the question here I also sent a question to the developer of the software to see if they had a solution to the issue. I believe with proper coding they should be able to solve this one. I only hoped that there was another solution which didn't involved contacting the developer. If you do think of something, please feel free to post the suggestion as a comment. Otherwise I shall be closing this question soon.
Thanks again.
Thanks again.
Well, I may have found a solution. Call the following method early on in your code (Main method, right before you call Application.Run is ideal)
System.Windows.Forms.Appli cation.Thr eadExcepti on += Application_ThreadExceptio n; // Or choose a different name, doesn't matter
Then, implement the following method (or use an anonymous method and place it above--again, doesn't matter)
System.Windows.Forms.Appli
Then, implement the following method (or use an anonymous method and place it above--again, doesn't matter)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Whoops, hit submit somehow. Here's the method you need to implement:
static void Application_ThreadExceptio n(System.O bject sender, System.Threading.ThreadExc eptionEven tArgs excArgs)
{
// Handle the thread exception here
}
However, you should note that this code will basically catch ALL EXCEPTIONS. Your try-catch'es and such will take precedence and prevent this method from executing, but if ANY exception occurs thorughout your application, this method will execute. If you have a finally block and no catch-blocks are executed, but an exception is thrown in a try-block, your finally block is executed FIRST, immediately followed by your ThreadException handling method.
Hope that helped, and hope you even see this, heh,
Nate
static void Application_ThreadExceptio
{
// Handle the thread exception here
}
However, you should note that this code will basically catch ALL EXCEPTIONS. Your try-catch'es and such will take precedence and prevent this method from executing, but if ANY exception occurs thorughout your application, this method will execute. If you have a finally block and no catch-blocks are executed, but an exception is thrown in a try-block, your finally block is executed FIRST, immediately followed by your ThreadException handling method.
Hope that helped, and hope you even see this, heh,
Nate
ASKER
Thanks for your solution - looks like that worked. I had no idea that event event existed!
Open in new window