2013-07-23 2 views
0

Пользователи могут запускать несколько экземпляров сборок InMemory из основного приложения. Проблема заключается в том, что общедоступные переменные в сборках InMemory, похоже, перезаписывают друг друга. Есть ли способ исправить это?Публичные переменные помехи между сборщиками, созданными InMemory, из CodeDom

Я также попытался переименовать Оценщика пространства и оценщика классов по-разному на один экземпляр, но это не помогло.

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

После многих испытаний и испытаний я нашел решение. Это не имело ничего общего с переменными Public, а также изменение имени и имени класса для каждого экземпляра тоже не работало, каждая сборка кода все еще делила информацию взад и вперед. Итак, ответ ... Поскольку несколько экземпляров вызывались из одного и того же родительского приложения, объект _evaluator должен быть независимым для каждого экземпляра в коде компилятора и вызывающего кода.

В итоге я разрешил использовать 5 экземпляров, которые могут быть запущены одновременно из приложения Windows. Если один экземпляр закрыт, программа назначает следующий вызываемый экземпляр доступному идентификатору, который я храню в общих значениях List (Of ...). этот код здесь не показан о том, как назначать и удалять.

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 
Смежные вопросы