web-dev-qa-db-fra.com

Déchargement de l'assembly chargé avec Assembly.LoadFrom ()

Je dois vérifier le temps nécessaire à l'exécution de GetTypes () après avoir chargé le fichier DLL . Le code est le suivant.

Assembly assem = Assembly.LoadFrom(file);
sw = Stopwatch.StartNew();
var types1 = assem.GetTypes();
sw.Stop();
double time1 = sw.Elapsed.TotalMilliseconds;

Je voudrais décharger et recharger la dll pour vérifier le temps à consacrer à l'exécution de GetTypes () à nouveau.

  • Comment puis-je le décharger? assem = null est assez bon? 
  • Existe-t-il un moyen explicite d'appeler garbage collector pour récupérer la ressource allouée à assem?
46
prosseek

Malheureusement, vous ne pouvez pas décharger un assemblage une fois qu'il est chargé. Mais vous pouvez décharger un AppDomain. Ce que vous pouvez faire est de créer un nouvel AppDomain (AppDomain.CreateDomain (...)), de charger l'assembly dans cet appdomain pour pouvoir l'utiliser, puis de décharger l'appDomain si nécessaire. Lors du déchargement de l'AppDomain, tous les assemblys chargés ont été déchargés. (Voir référence )

Pour appeler le ramasse-miettes, vous pouvez utiliser 

GC.Collect(); // collects all unused memory
GC.WaitForPendingFinalizers(); // wait until GC has finished its work
GC.Collect();

GC appelle les finaliseurs dans un fil d’arrière-plan, c’est pourquoi vous devez attendre et appeler à nouveau Collect () pour vous assurer que vous avez tout supprimé.

32
slfan

Pouvez-vous utiliser un autre AppDomain?

AppDomain dom = AppDomain.CreateDomain("some");     
AssemblyName assemblyName = new AssemblyName();
assemblyName.CodeBase = pathToAssembly;
Assembly assembly = dom.Load(assemblyName);
Type [] types = Assembly.GetTypes();
AppDomain.Unload(dom);
67
Rene de la garza

Au lieu d'utiliser LoadFrom() ou LoadFile(), vous pouvez utiliser Load avec File.ReadAllBytes(). Avec cela, il n’utilise pas le fichier Assembly mais le lit et utilise les données lues.

Votre code ressemblera alors à

Assembly assem = Assembly.Load(File.ReadAllBytes(filePath));
sw = Stopwatch.StartNew();
var types1 = assem.GetTypes();
sw.Stop();
double time1 = sw.Elapsed.TotalMilliseconds;

De ici Nous ne pouvons décharger le fichier que si tous les domaines qu’il contient sont déchargés.

J'espère que cela t'aides.:)

30
Hardik

Vous ne pouvez pas décharger Assembly de l'AppDomain actuel. Mais vous pouvez créer un nouveau AppDomain, y charger des assemblages, exécuter du code dans le nouvel AppDomain puis le décharger. Vérifiez le lien suivant: MSDN

4

L'assemblage ne peut malheureusement pas être déchargé. De plus, si vous utilisez des domaines d'application, vous ne pourrez plus communiquer avec les api/assemblies de votre application principale.

La meilleure description du problème peut être trouvée ici:

Guide d'hébergement des scripts http://www.csscript.net/help/Script_hosting_guideline_.html

Si vous souhaitez exécuter du code C # sans communication avec votre application principale - la meilleure approche consiste à intégrer l'API de script C #:

https://github.com/oleg-shilo/cs-script/tree/master/Source/deployment/samples/Hosting/Legacy%20Samples/CodeDOM/Modifying%20script%20without%20restart

Et pour l'intégration, vous aurez besoin des packages suivants:

Script C #: http://www.csscript.net/CurrentRelease.html

Extension de Visual studio: https://marketplace.visualstudio.com/items?itemName=oleg-shilo.cs-script

Si toutefois vous souhaitez communiquer depuis votre script C # vers votre application, utiliser la même application que le nom de la variable appDomain avec le nom de l'assembly ne peut changer pour le moment, mais cela nécessite malheureusement de la mémoire vive et de l'espace disque.

Exemple de code: comment le faire peut être fait - peut être trouvé à partir d'ici:

https://github.com/tapika/cppscriptcore CsScriptHotReload.sln

Et voici la vidéo de démonstration:

https://drive.google.com/open?id=1jOECjj0_UPNdllwF4GWb5OMybWPc0PUV

0
TarmoPikaro