从 AppDomain 解析 InvalidOperationException

Resolving InvalidOperationException from AppDomain

我基本上使用这段代码在 AppDomains 中使用插件 运行

AppDomain appDomain = AppDomain.CreateDomain("MyDomain");
PluginLoader loader = appDomain.CreateInstanceFromAndUnwrap(
    Assembly.GetExecutingAssembly().Location, typeof(PluginLoader).FullName);
loader.LoadPlugIns();
AppDomain.Unload(appDomain);

LoadPlugIns 使用 Assembly.LoadFrom().

加载并运行插件程序集

这似乎是一个有据可查的典型设计模式(例如 How to Load an Assembly to AppDomain with all references recursively?)。一个例外可能是多个 AppDomain 可能会同时加载,进而加载相同的程序集文件。我看不出有任何原因会导致问题。

然而,在我的例子中,有时会抛出一个 InvalidOperationException 和这个堆栈跟踪:

System.InvalidOperationException: Handle is not initialized.
  at System.WeakReference.set_Target(Object value)
  at System.Runtime.Remoting.IdentityHolder.SetIdentity(Identity idObj, String URI, DuplicateIdentityOption duplicateOption)
  at System.Runtime.Remoting.IdentityHolder.FindOrCreateIdentity(String objURI, String URL, ObjRef objectRef)
  at System.Runtime.Remoting.RemotingServices.InternalUnmarshal(ObjRef objectRef, Object proxy, Boolean fRefine)
  at System.Runtime.Remoting.RemotingServices.CreateProxyForDomain(Int32 appDomainId, IntPtr defCtxID)
  at System.AppDomain.GetDefaultDomain()
  at System.AppDomain.get_EvidenceNoDemand()
  at System.AppDomain.get_Evidence()
  at System.IO.IsolatedStorage.IsolatedStorage.InitStore(IsolatedStorageScope scope, Type domainEvidenceType, Type assemblyEvidenceType)
  at System.IO.IsolatedStorage.IsolatedStorageFile.GetStore(IsolatedStorageScope scope, Type domainEvidenceType, Type assemblyEvidenceType)
  at MS.Internal.IO.Packaging.PackagingUtilities.ReliableIsolatedStorageFileFolder.Dispose(Boolean disposing)
  at MS.Internal.IO.Packaging.PackagingUtilities.ReliableIsolatedStorageFileFolder.Finalize()

我很难理解为什么会发生这种情况以及如何解决它。似乎我的代码没有触发异常。所以没有机会在 try/catch 块中捕获它。我尝试按照 Unregister Lease throws InvalidOperationException 中的建议注册 AppDomain,但无济于事。

为了防止其他人遇到同样的问题,像这样创建 AppDomain 似乎可以解决问题。

Evidence evidence = AppDomain.CurrentDomain.Evidence
AppDomain appDomain = AppDomain.CreateDomain("MyDomain", evidence);