I have an annyoing problem with an OEM USB camera. It's drivers are quite poor and I have found one bug the vendor did not even know about. My Labview application calls the vendor's DLLs and it appears the DLLs never exit on occasions (roughly once per day).
Unlike C#, Labview cannot abort a threat with a stuck DLL in it.
However I have made the camera control modular as a sub vi. I am considering having the higher level VI unload and reload the sub vi if a timeout occurs, so we can recover from a hung DLL.
Anyone know if this can be done?
I shoud mention this camera is occasionally lost from the system devices because Windows 7 detects it as faulty. Replugging the camera and restarting the Labview EXE or the OEM camera demo EXE does not find the camera. There is nothing wrong with the USB power or signals. The PC has to be rebooted and then it all works. I suspect the Windows registry is being modified with a flag stating the camera is bad, and rebooting it fixes it. I have had a gut full of this camera and am looking at an alternative.
> However I have made the camera control modular as a sub vi. I am considering having the higher level VI unload and reload the sub vi if a timeout
> occurs, so we can recover from a hung DLL.
> Anyone know if this can be done?
That might not work as it's waiting for the return from the dll.
Make your camera VI ( the one calls the dll) a seperate executable.
If that exe hang, you can kill it.
What you are asking for really doesn't work properly in _any_ situations. Being a C/C++ developer, I was curious how .NET's Abort method actually works, since such a concept really does not exist in unmanaged code. If you'll notice Microsoft's documentation (http://msdn.microsoft.com/en-us/library/vstudio/ty8d3wta(v=vs.100).aspx), the answer is that it only works in managed code (where its runtime allows asynchronous exceptions):
"If Abort is called on a managed thread while it is executing unmanaged code, a ThreadAbortException is not thrown until the thread returns to managed code."
Thus, if the DLL you are calling happens to also be .NET managed code, then I suppose calling Abort from some other .NET managed code might work. However, there are a laundry list of caveats to this (the caller's exception handling can block indefinitely or ignore the exception, or leave all sorts of resources in unexpected states) such that relying on it seems destined to fail.
To be fair, there is a specific mechanism specific to the Win32 API for aborting a thread asynchronously: TerminateThread - http://msdn.microsoft.com/en-us/library/ms686717.aspx
However, this is even more dangerous than the .NET version since generic unmanaged code and the model of execution doesn't have any such way to attempt to do this safely. Per their documentation:
TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems:
Even if you weren't scared off by this, it would require much coordination with LabVIEW to make this work. Since re-uses threads in its execution model, if you were to kill one you'd leave its state and all its interaction with internal LabVIEW data structures inconsistent.
Your only two reasonable options seem to be:
- Follow George's suggestion and make your camera VI into a executable that can run out-of-process and exchange data with your caller via VI server/TCP/shared variables
- Use a different camera with good drivers that don't have this issue. Unless you have very specific camera requirements, there are tons at any price point (from $5 USD and up) that work with NI-IMAQdx very well