views:

528

answers:

1

Using Visual Studio 2005.

Here's an interesting one.

To reproduce, create new solution with windows application and class library.

In class library, define class like this :

public class SomeClassInDLL
{
 public string DoSomething()
 {
  return DateTime.Now.ToString();
 }
}

Get the windows app to reference the class library. Add a button, and add this code :

 private void button1_Click(object sender, EventArgs e)
 {
  try
  {
   MessageBox.Show("about to call DoSomething");
   string ret = DoCall();
   MessageBox.Show(ret);
  }
  catch (Exception ex)
  {
   MessageBox.Show("error : " + ex.GetType().ToString() + " " + ex.Message);

  }
 }

 private string DoCall()
 {
  SomeClassInDLL c1 = new SomeClassInDLL();
  return c1.DoSomething();
 }

1) Compile the app in both Debug and Release modes. (into the bin\Debug and bin\Release directories)

2) Close down visual studio, and run windows app from Windows explorer

3) Click button 1.

4) When the "about to call DoSomething" dialog comes up, in windows explorer, try to delete the referenced dll file.

5a) if you ran the debug mode version in step 2 : you can delete the dll file successfully.This is what I expect, since the dll is being called inside the DoCall function, and not directly in button1_Click.

5b) if you ran the release mode version in step 2 : you cannot delete the dll file, because it seems to be locked by the application.

==

5a) is the behaviour I have come to expect, since dotnet 1.1 days. Any ideas why 5b) seems to lock the dll earlier than necessary ? Something to do with optimization perhaps ? Is this sort of dll loading behaviour explained somewhere ?

TIA.

+1  A: 

In release mode the DoCall function is likely to be inlined into the button click event handler.

This means the type loader needs to know about SomeClassInDll a lot earlier (hence the lock on the dll)

Note that relying on this behaviour is dangerous, the type load can easily be triggered through reflection, by changes in the inlining heuristics or by changes in the type loader (making speculative jit loading of dependent methods for example - though that is unlikely)

ShuggyCoUk