我正在编写一个多线程解决方案,用于将来自不同源的数据传输到中央数据库。该解决方案通常包括两个部分:
脚本引擎用于允许输入和输出之间的自定义转换。对于每个输入/输出对,都有一个带有自定义脚本的文本字段。这是用于脚本初始化的简化代码:
稍后我们将使用以下代码调用此脚本:
因此,在导入定义初始化之后,我们可能会有任意数量的输入/输出对描述以及脚本对象,其中每个配对在定义脚本时增加了约50 MB的内存占用。在将目标行存储到数据库之前,还要对目标行进行验证(每个字段可能有多个脚本用于检查数据的有效性)。
总的来说,具有适度转换/验证脚本的典型内存占用量为每个线程200 MB。如果我们需要调用多个线程,则内存使用量将非常高,99%将用于脚本编写。 如果导入引擎被包含在基于WCF的中间层中(我这样做了),我们很快就会遇到“内存不足”的问题。
显然的解决方案是拥有一个脚本实例,该实例将根据需要(输入/输出转换,验证或其他内容)将代码执行分派到脚本内的特定函数。也就是说,我们将SCRIPT_ID作为全局参数传递到脚本引擎中,而不是为每个字段提供脚本文本。在脚本的某个位置,我们需要切换到执行并返回适当值的特定代码部分。
这种解决方案的好处应该是更好的内存使用率。缺点是脚本维护从其使用的特定点中移除了。
在实施此更改之前,我想听听关于此解决方案的意见和不同方法的建议。
- 单线程导入引擎
- 调用导入引擎的多线程客户端。
脚本引擎用于允许输入和输出之间的自定义转换。对于每个输入/输出对,都有一个带有自定义脚本的文本字段。这是用于脚本初始化的简化代码:
//Instance of class passed to script engine
_ScriptHost = new ScriptHost_Import();
if (Script != "") //Here we have script fetched from DB as text
{
try
{
//We are creating script object …
ScriptObject = CSharpScript.Create<string>(Script, globalsType: typeof(ScriptHost_Import));
//… and we are compiling it upfront to save time since this might be invoked multiple times.
ScriptObject.Compile();
IsScriptCompiled = true;
}
catch
{
IsScriptCompiled = false;
}
}
稍后我们将使用以下代码调用此脚本:
async Task<string> RunScript()
{
return (await ScriptObject.RunAsync(_ScriptHost)).ReturnValue.ToString();
}
因此,在导入定义初始化之后,我们可能会有任意数量的输入/输出对描述以及脚本对象,其中每个配对在定义脚本时增加了约50 MB的内存占用。在将目标行存储到数据库之前,还要对目标行进行验证(每个字段可能有多个脚本用于检查数据的有效性)。
总的来说,具有适度转换/验证脚本的典型内存占用量为每个线程200 MB。如果我们需要调用多个线程,则内存使用量将非常高,99%将用于脚本编写。 如果导入引擎被包含在基于WCF的中间层中(我这样做了),我们很快就会遇到“内存不足”的问题。
显然的解决方案是拥有一个脚本实例,该实例将根据需要(输入/输出转换,验证或其他内容)将代码执行分派到脚本内的特定函数。也就是说,我们将SCRIPT_ID作为全局参数传递到脚本引擎中,而不是为每个字段提供脚本文本。在脚本的某个位置,我们需要切换到执行并返回适当值的特定代码部分。
这种解决方案的好处应该是更好的内存使用率。缺点是脚本维护从其使用的特定点中移除了。
在实施此更改之前,我想听听关于此解决方案的意见和不同方法的建议。