Hi,
I found the attached example (classes are not complete, but enough for explanation):
public class RegistryKey : IDisposable
{
...
[DllImport("advapi32.dll", CharSet=CharSet.Auto)]
static extern int RegDeleteKey(IntPtr hKey, string lpSubKey);
public void DeleteSubKey(string subKey)
{
// Delete the subkey
int result = RegDeleteKey(hKey, subKey);
if (result != 0)
throw new ApplicationException("Could not delete registry key: " +
ErrorHelper.GetErrorMessage(result));
}
}
A C# client might use this as follows:
public class Client
{
static readonly IntPtr HKEY_LOCAL_MACHINE =
new IntPtr(unchecked((int)0x80000002));
public static void Main()
{
RegistryKey key =
new RegistryKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\.NET and COM");
key.DeleteSubKey("TemporaryKey");
}
}
with this comment:
The call to DeleteSubKeyis the last time the RegistryKeyinstance is used, and the implementation of DeleteSubKeycalls a PInvoke method with parameter types that don't keep the object alive (a simple by-value IntPtrand string). Therefore, there's a rare chance that the call to DeleteSubKey will cause an exception to be thrown. Right before the PInvoke call to RegDeleteKey, the garbage collector could free the RegistryKeyinstance because there's no further use of it anywhere in the program. (Had thisbeen passed to a PInvoke method, the instance would not be eligible for collection.) If this happens, and if the object's finalizer runs beforeRegDeleteKeyuses the HKEYpassed to it, an ApplicationExceptionwould be thrown with the message, "The handle is invalid," due to the finalizer's call to RegCloseKey.
And question is: is it possible for GC to free obj. instance inside the method of the same instance? If yes, is it the same in vb.net?
It's pretty crazy, I think...
Loading
VulpesPosted Jun 19, 2014, 8:29 AM
If this were possible and, if DeleteSubKey called another of RegistryKey's instance methods before returning, then that method call would fail because the object would no longer exist!
VulpesPosted Jun 24, 2014, 8:31 AM
I remember reading years ago that the /optimize compiler switch didn't do anything very profound and that blog post by Eric Lippert seems to bear that out.
The JIT will no doubt do more but, AFAIK, there's no way to control that. Given that it has to work in 'real time', there will also be a limit to what the JIT can do compared to, say, a C++ optimizing compiler.
Libor TheimerPosted Jun 23, 2014, 4:33 PM
VulpesPosted Jun 22, 2014, 7:46 PM
Yes, the behavior of the GC will be the same for all .NET applications, whatever language they were originally written in.
My own view is that you just have to live with all this if you write .NET applications and to take suitable precautions if you want to ensure that certain operations will always occur in the intended order.
Libor TheimerPosted Jun 22, 2014, 6:02 PM
VulpesPosted Jun 22, 2014, 1:29 PM
Of course, with stuff like this, you could run the application a thousand times without seeing any problem. If and when a problem does occur, it's going to be extremely difficult to debug unless you're aware of what can happen in .NET's 'garbage collected' world.
?????? ???????Posted Jun 22, 2014, 5:33 AM
Actually, it IS possible and perfectly legal for GC to 'free' an object even while its constructor (!!) is running. Mr. Lippert has written a nice (as always:)) blog post on the subject: http://ericlippert.com/2013/06/10/construction-destruction/
But in your case, as far as I can see there is NO chance for such a 'situation' since DeleteSubKey method uses a reference to hKey field of the object and no optimizer can change it;
Of course, I can not not be AbsolutelY sure that it cannot be GC'ed. The real dark magic is always out there. So the best way to check it out is to write a test and catch that exception) Haven't you tried it yet?
Libor TheimerPosted Jun 21, 2014, 5:50 PM
VulpesPosted Jun 19, 2014, 6:42 PM
Suppose also that the DeleteSubKey method were to call another instance method of the same class before returning (I know it's not doing that in the example but in practice it could do that).
Then the call to the other instance method would fail because the object no longer existed.
This is the point I was trying to make in the last paragraph of my previous post and would clearly be a serious bug in the GC subsystem.
I have the greatest respect for Adam Nathan and this particular book which was the standard work on interoperability in the early years of .NET. However, I think this example must either be wrong or there actually was a bug in the GC at the time which (hopefully) has now been addressed.
Libor TheimerPosted Jun 19, 2014, 5:58 PM
But my english is not very good and I don't exactly understand to your last paragraph.
Thank You
LT