我需要能够在F#交互中创建新的AppDomain以便承载多个WPF应用程序。对于在已编译的F#应用程序中运行所需的功能,我没有任何问题,但是由于某种原因,似乎无法在F#交互式环境中运行该功能。
这是最简单的情况:
#r "PresentationCore.dll"
#r "PresentationFramework.dll"
#r "System.Xaml.dll"
#r "WindowsBase.dll"
open System
open System.Threading
open System.Windows
type myClass() =
let domain = AppDomain.CreateDomain("another domain")
//this function starts a WPF app
let funct() =
let WPFStart() =
let app = Application()
let win = Window()
app.Run(win) |> ignore
let thread = Thread WPFStart
thread.IsBackground <- true
thread.SetApartmentState ApartmentState.STA
thread.Start()
do CrossAppDomainDelegate(funct) |> domain.DoCallBack
myClass();;
我总是从中得到一些东西
System.Runtime.Serialization.SerializationException: Type is not resolved
for member 'FSI_0002+-ctor@24,FSI-ASSEMBLY, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null'.
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at FSI_0002.myClass..ctor()
at <StartupCode$FSI_0005>.$FSI_0005.main@()
Stopped due to error
我需要做什么才能使其在F#交互式环境中正常工作?
最佳答案
docs的简介:
主要问题在于编译步骤
typeof<myClass>.Assembly.FullName
输出:
为了编译代码,fsi使用动态程序集来承载在 session 期间创建的所有类型。此处的关键要素是,其他域在不引用包含该程序集的情况下将无法解析这些类型。然而,事实证明,从其他应用程序域中获取程序集并非易事。主要是因为我们要处理动态装配。
let asm = typeof<myClass>.Assembly
asm.IsDynamic // val it : bool = true
这意味着,它仅存在于fsi的默认appdomain的内存中。下面的两个查找均抛出
asm.Location
asm.CodeBase
通常,您要先保留到磁盘,请参阅remarks-向远程应用程序域发出限制:
成功地将动态程序集转换为
AssemblyBuilder
将公开Save
方法。不幸的是,该工作流程也已被封锁。open System.Reflection.Emit
let builder = asm :?> AssemblyBuilder
throw
我们正在处理内部类型,显然我们不打算弄脏我们的手。从referencesource.microsoft.com:
另外,您可以使用
new AssemblyBuilder
和System.Reflection.Emit
命名空间中的其他帮助器来反射(reflect)动态程序集和reconstruct them中的类型,但这似乎有点乏味。总结一下,当前实现的方式将使您流向流,以尝试将fsi生成的类型公开给其他域。
关于.net - 在F#Interactive中创建新的AppDomain,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50349820/