Groups | Blog | Home
all groups > dotnet clr > november 2004 >

dotnet clr : How prevent the crash and exit gracefully?


Boris
11/29/2004 3:37:03 PM
I notice the following strange behavior of the applications running under
..NET Framework.

Let say I have application MyApp.exe which reference assembly MyAssembly.dll.
The MyAssembly.dll is strong named assembly, which is installed in the GAC.

I notice that if MyAssembly.dll is not installed in GAC or the different
version of MyAssembly.dll is installed in GAC then MyApp.exe starts OK. But
as soon as the MyApp.exe app tries to call any function from the
MyAssembly.dll the MyApp.exe application crashes.

In unmanaged VC++ 6.0 world the application wouldn't even allowed to start
if some dll are missing. The system would display error message saying that
some dll's are missing and application would gracefully exit.

I wonder whether I misunderstand something or made any mistake? Why
MyApp.exe is allowed to start in order to crash right after attemp to use any
functionality from missing dependent assembly?

I was told that CLR doesn't load anything untill it needs it. OK, but how to
prevent the crash I described above and exit gracefully like in VC++ 6.0
case?

Can anyone clarify this situation?
Thanks
Richard Blewett [DevelopMentor]
11/30/2004 5:01:53 AM
<sigh>

Obviously I meant it does delay loading to *decrease* application startup time

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk


This is by design. the CLR does delay loading of assemblies to both increase
application startup time and to forgoe the overhead of loading an assembly
that ends up not being used.
Richard Blewett [DevelopMentor]
11/30/2004 10:21:36 AM
[quoted text, click to view]

This is by design. the CLR does delay loading of assemblies to both increase
application startup time and to forgoe the overhead of loading an assembly
that ends up not being used.

[quoted text, click to view]

Not if you turn on delay loading for a DLL

[quoted text, click to view]

Here is some code that will preload your assemblies:

using System;
using System.Reflection;
using System.Collections;
using System.Text;

class App
{
static void Main(string[] args)
{
PleaseSlowDownMyApplicationStartup();

RestOfApplication();
}

static void RestOfApplication()
{
// the rest of the application needs to be
// in another method otherwise the JIT compiler will
// load the assembleis and potentially fail outside of this
// functionality
}

static ArrayList missingAssemblies = new ArrayList();

static void PleaseSlowDownMyApplicationStartup()
{
LoadDependencies(Assembly.GetExecutingAssembly().GetName());

if( missingAssemblies.Count > 0 )
{
throw new AssemblyDependencyException(string.Format("{0} assemblies
were either missing or unloadable", missingAssemblies.Count),
missingAssemblies);
}
}

static void LoadDependencies(AssemblyName name)
{
try
{
Assembly a = Assembly.Load(name);
foreach(AssemblyName depends in a.GetReferencedAssemblies())
{
LoadDependencies(depends);
}
}
catch(Exception)
{
missingAssemblies.Add(name);
}
}
}

class AssemblyDependencyException : Exception
{
public AssemblyDependencyException( string msg, ArrayList
incorrectAssemblies )
: base(msg)
{
incorrect = incorrectAssemblies;
}
ArrayList incorrect;
public override string ToString()
{
StringBuilder sb = new StringBuilder();
foreach( AssemblyName name in incorrect )
{
sb.Append(name.ToString());
sb.Append(Environment.NewLine);
}
return sb.ToString();
}
}

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

AddThis Social Bookmark Button