샌드 박스 AC# 스크립트 컴파일러를로드하는 방법을 연구 한 후로드 된 어셈블리가 기본 AppDomain이 아닌 샌드 박스 AppDomain에만로드되도록 실행했습니다. 모든 dll 파일을 AppDomain 샌드 박스를 언로드 할 때 언로드합니다.AppDomain을 언로드 한 후 모든 어셈블리가 해제됩니다.
이return new Func<List<int>,int>
(
(list) =>
{
var total = 0;
foreach (int i in list)
{
total += i;
}
return total;
}
);
이제 어떻게 스크립트의 반환에 발생하는 그들은 모두 결국 기본 응용 프로그램 도메인에 사전에 반환이다 : 그것은 하나처럼 보이는 스크립트입니다. 나머지 스크립트는 모두 간단한 직렬화 가능 객체 또는 프리미티브를 반환하며 모든 어셈블리가 올바르게 언로드되었다고 말했고 여전히 기본 도메인을 사용하여 삭제할 수있었습니다. 이 특정 반환 값이 Func이므로 기본 AppDomain에 생성 어셈블리를 "전달"해야합니까? 이 주변에 방법이 없을까요?
처음부터 샌드 박스가있는 이유는 스크립트 집합을 실행 한 후에 실행 한 개체를 처리 할 수 있고 dispose 메서드가 샌드 박스 도메인을 언로드하고 생성 된 어셈블리를 모두 삭제하기 때문입니다. 어셈블리의 빌드가 문제가되는 웹 서버와 같이 지속적으로 실행되는 환경에서 이것을 사용할 수 있기를 원합니다. 현재 스크립트 세트가 Func을 반환 할 때마다 느린 어셈블리가 있습니다. 차라리이 라이브러리를 사용하는 문서 옆에 별표가 없으므로 어떤 아이디어라도 환영받을 것입니다.
var provider = new CSharpCodeProvider(new Dictionary<string, string>() { { CompilerOptionName, CompilerOptionVersion } });
var compilerParams = new CompilerParameters { GenerateExecutable = false, GenerateInMemory = false };
compilerParams.ReferencedAssemblies.AddRange(References);
compilerParams.TempFiles = new TempFileCollection(BinPath);
compilerParams.OutputAssembly = Path.Combine(BinPath,
Utilities.AssemblyPrefix + ProfigurationExe.Profiguration.ID + "_" + Action.ID + "_Script" + Utilities.DllExt);
// If no object is returned by user code, enter in a return null to satisfy returning an object for
// default code template. If they do have a return that will return first.
Code = Code + ReturnNull;
var parameterString = BuildParameterString();
parameterString = !String.IsNullOrEmpty(parameterString) ? ", " + parameterString : String.Empty;
// If someone simply imports namespaces separated by spaces, commas, or semicolons, create a proper using statement
if (!String.IsNullOrEmpty(Imports) && !IsUsingRegex.IsMatch(Imports))
{
Imports = String.Join("; ", Imports.Split(" ,;".ToCharArray()).Select(s => Using + " " + s)) + "; ";
}
FinalCode = String.Format(Imports + CodeTemplate,
new object[] {DefaultNamespace, ClassName, DefaultMethod, parameterString, Code});
// This just is a variable of the code that will be compiled, with all spaces and line breaks removed
var debugFriendlierFinalCode = U.CompressWhiteSpaceRegex.Replace(FinalCode.Replace("\r", String.Empty).Replace("\n", String.Empty), U.OneSpace);
// Note that we are adding the import fields to the beginning in case user wants to import namespaces (and not have to always use fully qualified class names)
var results = provider.CompileAssemblyFromSource(compilerParams, FinalCode);
Assembly = results.CompiledAssembly;
if (!results.Errors.HasErrors)
{
return Assembly;
}
// If there were compiler errors, aggregrate them into an exception.
var errors = new StringBuilder("Dynamic Code Compiler Errors :\r\n");
foreach (CompilerError error in results.Errors)
{
errors.AppendFormat("Line {0},{1}\t: {2}\n",
error.Line, error.Column, error.ErrorText);
}
throw new ProfigurationException(errors.ToString());
http://msdn.microsoft.com/en-us/library/system.marshalbyrefobject%28v=vs.110%29.aspx –
감사합니다. 예, 도메인간에 전달되는 모든 객체에 대해이를 사용합니다. –