Ich verwende eine .dll-Referenz für meine Anwendung. Ich möchte die .dll in einer Schaltfläche Klick-Ereignis zu entladen. Wie es zu tun?
Antworten
Zu viele Anzeigen?Sie können keine einzelne Baugruppe entladen - Sie müssen eine ganze Baugruppe entladen. AppDomain
. Mit anderen Worten, Sie müssen Ihre andere Assembly (und den zugehörigen Code) in eine neue AppDomain
und dann, wenn Sie es entladen wollen, entladen Sie die AppDomain
.
Natürlich macht dies das Leben viel schwieriger, da man sich um das Marshalling von Aufrufen zwischen AppDomains kümmern muss - aber das ist alles, was .NET erlaubt.
Wie Jon Skeet schrieb, können Sie eine DLL nicht entladen, aber Sie können die DLL in eine andere AppDomain laden - und dann die AppDomain entladen. Das ist der einzige Weg, dies zu tun.
Es gibt jedoch einige Dinge, die Sie beachten müssen, da Sie natürlich Funktionen über die AppDomain aufrufen müssen. Dies kann auf zwei verschiedene Arten geschehen.
Wenn Sie von einer AppDomain (nennen wir sie A) einen Verweis auf ein Objekt erhalten, das in AppDomain B instanziiert wurde, dann wird das Objekt standardmäßig über die AppDomain-Grenze hinweg serialisiert. Das bedeutet, dass die Objektinstanz, auf die A zugreift, nicht dieselbe Instanz ist, auf die B zugreift, und dass Änderungen, die in A vorgenommen werden, nicht in B wiedergegeben werden, es sei denn, Sie stellen eine Funktionalität bereit, um das Objekt zurückzusenden. Dies erfordert, dass das Objekt mit Serializable markiert ist.
Sie können jedoch die Serialisierung vermeiden, indem Sie die Klasse von MarshalByRefObject erben lassen. Wenn das Objekt in AppDomain B erstellt und von AppDomain A aus aufgerufen wird, überschreitet der Aufruf die AppDomain-Grenze. Es wird immer noch derselbe physische Thread sein, so dass Sie nicht den Overhead eines Threadwechsels wie bei prozessübergreifenden Aufrufen oder COM-übergreifenden Aufrufen haben.
Wenn Sie jedoch ein Objekt in B konstruieren, das von einem Objekt in A referenziert wird, aber auf das Objekt in B 5 Minuten lang nicht zugegriffen wird, wird das Objekt entsorgt. Dieses Verhalten kann in MarshalByRefObject.InitializeLifetimeService() außer Kraft gesetzt werden.
Siehe auch die Antwort auf Implementierung von .NET-Plug-ins ohne AppDomains . Beachten Sie die Diskussion in den Kommentaren, wo sie darauf hinweisen, dass es sehr langsam leckt Speicher.