如何在多个脚本的批处理中使用Roslyn C#脚本?
我正在编写multithreading解决方案,用于将数据从不同的源传输到中央数据库。 解决方案通常包含两部分:
- 单线程导入引擎
- 在线程中调用Import引擎的multithreading客户端。
为了最大限度地减少自定义开发,我使用的是Roslyn脚本。 导入引擎项目中的Nuget包管理器启用了此function。 每个导入都被定义为输入表的转换 – 具有输入字段的集合 – 再次转换为目标表 – 再次使用目标字段的集合。
此处使用脚本引擎允许输入和输出之间的自定义转换。 对于每个输入/输出对,都有带自定义脚本的文本字段。 以下是用于脚本初始化的简化代码:
//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(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 RunScript() { return (await ScriptObject.RunAsync(_ScriptHost)).ReturnValue.ToString(); }
因此,在导入定义初始化之后,我们可能有任意数量的输入/输出对描述以及脚本对象,在定义脚本的情况下,每对内存占用量增加大约50 MB。 在将目标行存储到DB之前,类似的使用模式将应用于目标行的validation(每个字段可能有多个脚本用于检查数据的有效性)。
总而言之,具有适度转换/validation脚本的典型内存占用量为每个线程200 MB。 如果我们需要调用多个线程,内存使用率将非常高,99%将用于脚本编写。 如果导入引擎被快速封装在基于WCF的中间层(我做了)中,我们会发现“内存不足”问题。
显而易见的解决方案是有一个脚本实例,它会以某种方式将代码执行调度到脚本内的特定函数,具体取决于需要(输入/输出转换,validation或其他)。 即,不是每个字段的脚本文本,我们将有SCRIPT_ID,它将作为全局参数传递给脚本引擎。 在脚本的某处,我们需要切换到将执行并返回适当值的特定代码部分。
这种解决方案的好处应该是更好的内存使用。 缺点是脚本维护从使用它的特定点移除。
在实施此更改之前,我想听听有关此解决方案的意见以及针对不同方法的建议。
看起来 – 使用脚本执行任务可能是一种浪费的过度杀伤 – 你使用许多应用程序层并且内存已满。
其他方案:
但是如果您仍然认为脚本是适合您的工具,我发现可以通过在应用程序中运行脚本工作来降低脚本的内存使用量(而不是使用RunAsync),您可以从RunAsync返回逻辑,并重新使用它,而不是在繁重和内存浪费的RunAsync
。 这是一个例子:
而不是简单的(脚本字符串):
DoSomeWork();
你可以这样做(IHaveWork是你app中定义的界面,只有一种方法可用):
public class ScriptWork : IHaveWork { Work() { DoSomeWork(); } } return new ScriptWork();
这样你只能在短时间内调用繁重的RunAsync,它会返回一个你可以在你的应用程序中重复使用的worker(你当然可以通过向Work方法添加参数来扩展它,并从你的应用程序inheritance逻辑,所以上…)。
该模式还打破了您的应用程序和脚本之间的隔离,因此您可以轻松地从脚本中提供和获取数据。
编辑
一些快速基准:
这段代码:
上述就是C#学习教程:如何在多个脚本的批处理中使用Roslyn C#脚本?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
static void Main(string[] args) { Console.WriteLine("Compiling"); string code = "System.Threading.Thread.SpinWait(100000000); System.Console.WriteLine(" Script end");"; List
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1009642.html