用户可以从主应用程序启动多个InMemory程序集实例。 问题是InMemory程序集中的公共变量似乎互相覆盖。有办法解决这个问题吗?
我还尝试将命名空间评估程序和类评估程序重命名为不同的实例,但这没有帮助。
Namespace Evaluator
Public Module GlobalSettings
Public Var1 As String
Public Var2 As String
Public TextBox1 As New TextBox
Public TextBox2 As New TextBox
End Module
Public Class Evaluator
'...insert code here
End Class
End Namespace
Friend Function CompileCode() As Object
Dim compResults As CompilerResults
Dim code = GetCode()
Dim provOptions As New Dictionary(Of String, String)
provOptions.Add("CompilerVersion", "v3.5")
Dim vbProv = New VBCodeProvider(provOptions)
Dim vbParams = New CompilerParameters()
vbParams.ReferencedAssemblies.Add("mscorlib.dll")
vbParams.ReferencedAssemblies.Add("System.dll")
vbParams.ReferencedAssemblies.Add("System.Windows.Forms.dll")
vbParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll")
vbParams.ReferencedAssemblies.Add("System.Data.dll")
vbParams.TreatWarningsAsErrors = False
vbParams.GenerateExecutable = False
vbParams.GenerateInMemory = True
compResults = vbProv.CompileAssemblyFromSource(vbParams, code)
_evaluator = compResults.CompiledAssembly.CreateInstance("Evaluator.Evaluator")
End Function
答案 0 :(得分:0)
经过大量的试验和测试,我找到了解决方案。它与Public变量无关,并且每个实例的Namespace和Class名称也不起作用,每个代码程序集仍然来回共享信息。所以答案...... 因为多个实例是从同一个父应用程序调用的,所以_evaluator对象需要对Compiler代码和Invoking代码中的每个实例都是独立的。
我最终允许从Windows应用程序同时启动的5个实例。如果一个实例被关闭,那么程序将下一个被调用的实例分配给我存储在公共List(Of ...)配对值中的可用id。此处未显示有关如何分配和删除的代码。
Dim _evaluator1 As Object
Dim _evaluator2 As Object
Dim _evaluator3 As Object
Dim _evaluator4 As Object
Dim _evaluator5 As Object
Friend Function CompileCode() As Object
Dim compResults As CompilerResults
Dim code = GetCode()
Dim provOptions As New Dictionary(Of String, String)
provOptions.Add("CompilerVersion", "v3.5")
Dim vbProv = New VBCodeProvider(provOptions)
Dim vbParams = New CompilerParameters()
vbParams.ReferencedAssemblies.Add("mscorlib.dll")
vbParams.ReferencedAssemblies.Add("System.dll")
vbParams.ReferencedAssemblies.Add("System.Windows.Forms.dll")
vbParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll")
vbParams.ReferencedAssemblies.Add("System.Data.dll")
vbParams.TreatWarningsAsErrors = False
vbParams.GenerateExecutable = False
vbParams.GenerateInMemory = True
compResults = vbProv.CompileAssemblyFromSource(vbParams, code)
Select Case CurrentInstance
Case 1 : _evaluator1 = compResults.CompiledAssembly.CreateInstance("Evaluator.Evaluator")
Case 2 : _evaluator2 = compResults.CompiledAssembly.CreateInstance("Evaluator.Evaluator")
Case 3 : _evaluator3 = compResults.CompiledAssembly.CreateInstance("Evaluator.Evaluator")
Case 4 : _evaluator4 = compResults.CompiledAssembly.CreateInstance("Evaluator.Evaluator")
Case 5 : _evaluator5 = compResults.CompiledAssembly.CreateInstance("Evaluator.Evaluator")
End Select
End Function
调用
Dim objResult As Object
Select Case CurrentInstance
Case 1 : objResult = _evaluator1.GetType.InvokeMember(name, BindingFlags.DeclaredOnly Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.InvokeMethod, Nothing, _evaluator1, args)
Case 2 : objResult = _evaluator2.GetType.InvokeMember(name, BindingFlags.DeclaredOnly Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.InvokeMethod, Nothing, _evaluator2, args)
Case 3 : objResult = _evaluator3.GetType.InvokeMember(name, BindingFlags.DeclaredOnly Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.InvokeMethod, Nothing, _evaluator3, args)
Case 4 : objResult = _evaluator4.GetType.InvokeMember(name, BindingFlags.DeclaredOnly Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.InvokeMethod, Nothing, _evaluator4, args)
Case 5 : objResult = _evaluator5.GetType.InvokeMember(name, BindingFlags.DeclaredOnly Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.InvokeMethod, Nothing, _evaluator5, args)
End Select