c#:实现动态编译,并实现动态MutilProcess功能(来自python mutilprocess的想法)

  由于之前一直遇到一些关于并行进行数据处理的时效果往往不好,不管是c#还是java程序都是一样,但是在Python中通过mutilprocess实现同样的功能时,却发现确实可以提高程序运行的性能,及服务器资源使用提高。python具体性能及mutilprocess用法,请参考:《Python:使用pymssql批量插入csv文件到数据库测试

  如有转载请标明原文地址:https://i.cnblogs.com/EditPosts.aspx?postid=7228337

  很久之前就设想如何在c#中实现多进程的方案,如今终于设计出了C#中动态实现多进程的方案:

具体代码:

  1 using Microsoft.CSharp;
  2 using System;
  3 using System.CodeDom;
  4 using System.CodeDom.Compiler;
  5 using System.Collections.Generic;
  6 using System.Linq;
  7 using System.Reflection;
  8 using System.Text;
  9
 10 namespace MutilProcessDemo
 11 {
 12     public class Program
 13     {
 14         static System.Timers.Timer timer = null;
 15
 16         public static void Main(string[] args)
 17         {
 18             GenerateExe();
 19
 20             timer = new System.Timers.Timer();
 21             timer.AutoReset = true;
 22             timer.Enabled = true;
 23             timer.Interval = 5000;
 24             timer.Elapsed += Timer_Elapsed;
 25
 26
 27             Console.WriteLine("Press Enter key to exit...");
 28             Console.ReadKey();
 29         }
 30
 31         private static void DynamicCompiler()
 32         {
 33             // 1.CSharpCodePrivoder
 34             CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider();
 35
 36             // 2.ICodeComplier
 37             ICodeCompiler objICodeCompiler = objCSharpCodePrivoder.CreateCompiler();
 38
 39             // 3.CompilerParameters
 40             CompilerParameters objCompilerParameters = new CompilerParameters();
 41             objCompilerParameters.ReferencedAssemblies.Add("System.dll");
 42             objCompilerParameters.GenerateExecutable = false;
 43             objCompilerParameters.GenerateInMemory = true;
 44
 45             // 4.CompilerResults
 46             CompilerResults cr = objICodeCompiler.CompileAssemblyFromSource(objCompilerParameters, GenerateCode());
 47
 48             if (cr.Errors.HasErrors)
 49             {
 50                 Console.WriteLine("编译错误:");
 51                 foreach (CompilerError err in cr.Errors)
 52                 {
 53                     Console.WriteLine(err.ErrorText);
 54                 }
 55             }
 56             else
 57             {
 58                 // 通过反射,调用HelloWorld的实例
 59                 Assembly objAssembly = cr.CompiledAssembly;
 60                 object objHelloWorld = objAssembly.CreateInstance("DynamicCodeGenerate.HelloWorld");
 61                 MethodInfo objMI = objHelloWorld.GetType().GetMethod("OutPut");
 62
 63                 Console.WriteLine(objMI.Invoke(objHelloWorld, null));
 64             }
 65
 66             Console.ReadLine();
 67         }
 68
 69         static string GenerateCode()
 70         {
 71             StringBuilder sb = new StringBuilder();
 72             sb.Append("using System;");
 73             sb.Append(Environment.NewLine);
 74             sb.Append("namespace DynamicCodeGenerate");
 75             sb.Append(Environment.NewLine);
 76             sb.Append("{");
 77             sb.Append(Environment.NewLine);
 78             sb.Append(" public class HelloWorld");
 79             sb.Append(Environment.NewLine);
 80             sb.Append(" {");
 81             sb.Append(Environment.NewLine);
 82             sb.Append(" public string OutPut()");
 83             sb.Append(Environment.NewLine);
 84             sb.Append(" {");
 85             sb.Append(Environment.NewLine);
 86             sb.Append(" return \"Hello world!\";");
 87             sb.Append(Environment.NewLine);
 88             sb.Append(" }");
 89             sb.Append(Environment.NewLine);
 90             sb.Append(" }");
 91             sb.Append(Environment.NewLine);
 92             sb.Append("}");
 93
 94             string code = sb.ToString();
 95             Console.WriteLine(code);
 96             Console.WriteLine();
 97
 98             return code;
 99         }
100
101
102         private static void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
103         {
104             System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName("HelloWorld.exe");
105
106             int maxProcessCount = 8;
107             // 如果超过了最大允许任务数据不再触发新的进程任务
108             if (processes.Length >= maxProcessCount)
109                 return;
110
111             List<int> tasks = new List<int>();
112             Random random = new Random(1000);
113             for (int i = 0; i < maxProcessCount - processes.Length; i++)
114             {
115                 tasks.Add(random.Next(1000));
116             }
117
118
119             System.Threading.Tasks.Task[] taskItems = new System.Threading.Tasks.Task[tasks.Count];
120
121             for (int i = 0; i < tasks.Count; i++)
122             {
123                 //TaskBase taskSubmit = new ParseMrToHdfsFileItemTask();
124                 //taskItems[i] = System.Threading.Tasks.Task.Factory.StartNew(taskSubmit.Submit, new ParseMrToHdfsFileItemTaskArgument() { Task = tasks[i], ComputeNode = this.ComputeNode }, TaskCreationOptions.PreferFairness);
125                 taskItems[i] = System.Threading.Tasks.Task.Factory.StartNew((object state) =>
126                 {
127                     System.Diagnostics.Process process = new System.Diagnostics.Process();
128                 //System.Diagnostics.Process process = System.Diagnostics.Process.Start("HelloWorld.exe", state.ToString());
129                 process.StartInfo = new System.Diagnostics.ProcessStartInfo();
130                     process.StartInfo.CreateNoWindow = true;
131                     process.StartInfo.UseShellExecute = false;
132                     process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
133                     process.StartInfo.Arguments = state.ToString();
134                     process.StartInfo.FileName = "HelloWorld.exe";
135                     process.Start();
136                     process.WaitForExit();
137                     process.Close();
138                     process.Dispose();
139                 }, tasks[i]);
140             }
141
142             System.Threading.Tasks.Task.WaitAll(taskItems);
143         }
144
145         private static void GenerateExe()
146         {
147             // 创建编译器对象
148             CSharpCodeProvider p = new CSharpCodeProvider();
149             ICodeCompiler cc = p.CreateCompiler();
150
151             // 设置编译参数
152             CompilerParameters options = new CompilerParameters();
153             options.ReferencedAssemblies.Add("System.dll");
154             options.ReferencedAssemblies.Add("MutilProcessDemo.exe");
155             options.GenerateExecutable = true;
156             options.OutputAssembly = "HelloWorld.exe";
157
158             //options.ReferencedAssemblies.Add("System.Windows.Forms.dll");
159             //options.EmbeddedResources.Add("Data.xml"); // 添加内置资源
160             //options.CompilerOptions += " /target:winexe";
161             //options.CompilerOptions += " /res:Resource1.res";
162             //options.CompilerOptions += " /win32icon:test.ico";
163
164             // 创建源码
165
166             // 1. 使用CodeDom创建源码
167             //CodeCompileUnit cu = new CodeCompileUnit();
168             //CodeNamespace Samples = new CodeNamespace("Samples");
169             //cu.Namespaces.Add(Samples);
170             //Samples.Imports.Add(new CodeNamespaceImport("System"));
171             //CodeTypeDeclaration Class1 = new CodeTypeDeclaration("Class1");
172             //Samples.Types.Add(Class1);
173             //CodeEntryPointMethod Start = new CodeEntryPointMethod();
174             //CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(
175             // new CodeTypeReferenceExpression("System.Console"), "WriteLine",
176             // new CodePrimitiveExpression("Hello World!")
177             // );
178             //Start.Statements.Add(new CodeExpressionStatement(cs1));
179             //Class1.Members.Add(Start);
180
181             // 2. 直接指定源码字符串
182             string code = @"
183 using System;
184 using MutilProcessDemo;
185
186 namespace Samples
187 {
188     public class Class1
189     {
190         static void Main(string[] args)
191         {
192             Console.WriteLine(""Hello, World!"");
193             MutilProcessDemo.Program.DoMethod(args);
194             Console.WriteLine(DateTime.Now.ToString());
195         }
196     }
197 }";
198             CodeSnippetCompileUnit codeSnippetCompileUnit = new CodeSnippetCompileUnit(code);
199
200             // 开始编译
201             CompilerResults compilerResults = cc.CompileAssemblyFromDom(options, codeSnippetCompileUnit);
202
203             // 显示编译信息
204             if (compilerResults.Errors.Count == 0)
205                 Console.WriteLine("{0}compiled ok!", compilerResults.CompiledAssembly.Location);
206             else
207             {
208                 Console.WriteLine("Complie Error:");
209                 foreach (CompilerError error in compilerResults.Errors)
210                     Console.WriteLine(" {0}", error);
211             }
212         }
213
214         public static void DoMethod(string[] args)
215         {
216             System.Console.WriteLine("begin ..." + args[0]);
217
218             for (int i = 0; i < int.Parse(args[0]); i++)
219             {
220                 System.Threading.Thread.Sleep(20);
221             }
222
223             System.Console.WriteLine("end..." + args[0]);
224         }
225     }
226 }

上边的程序运行之后会在\MutilProcessDemo\bin\Debug\下出现两个可执行的.exe:HelloWorld.exe、MutilProcessDemo.exe。

参考文章:

c#动态编译,程序集的动态创建(http://www.360doc.com/content/14/1014/11/5054188_416763069.shtml)

时间: 2024-10-07 12:45:26

c#:实现动态编译,并实现动态MutilProcess功能(来自python mutilprocess的想法)的相关文章

gcc 动态编译 动态库路径

gcc 动态编译(共享库) 动态编译的可执行文件需要附带一个的动态链接库,在执行时,需要调用其对应动态链接库中的命令优点:体积小,编译快缺点:依赖性高 代码如下: [[email protected] shared]# cat add.cint add (int x, int y) {return x + y;} Parsed in 0.007 seconds at 12.13 KB/sadd.c 求和函数 代码如下: [[email protected] shared]# cat print.

Java动态编译

Java动态编译 一.动态编译简介 new创建对象是静态加载类,在编译时刻就需要加载所有可能使用到的类. 一百个类,有一个类错了,都无法编译. 通过动态加载类可以解决该问题 二.代码实例 2.1 OfficeBetter.java main接口 里面通过对Class类的动态编译 然后调用实例,完成动态编译 1 public class OfficeBetter { 2 3 public static void main(String[] args) throws InstantiationExc

让C#语言充当自身脚本!——.NET中的动态编译

原文:让C#语言充当自身脚本!--.NET中的动态编译 代码的动态编译并执行是.NET平台提供给我们的很强大的一个工具,用以灵活扩展(当然是面对内部开发人员)复杂而无法估算的逻辑,并通过一些额外的代码来扩展我们已有 的应用程序.这在很大程度上给我们提供了另外一种扩展的方式(当然这并不能算是严格意义上的扩展,但至少为我们提供了一种思路). 动态代码执行可以应用在诸如模板生成,外加逻辑扩展等一些场合.一个简单的例子,为了网站那的响应速度,HTML静态页面往往是我们最好的选择,但基于数据驱动的网站往往

ANGULARJS 动态编译添加到dom中

在使用angularjs 时,希望通过动态构建angular模版,再通过angular进行展示. 使用 方法如下: <html ng-app="app"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <script src="assets/angular.min.js">

程序动态编译代码

c#可以在程序运行过程中动态的编译代码,并生成程序集加载在内存,然后就可以动态的调用代码生成的程序了,这有点像我们的vs编译器,感兴趣的可以制作属于自己的c#编译器: 要实现这种功能,我们只需要调用CSharpCodeProvider就可以实现了: string prefix = "using System;"+ "public static class Test{"+ "public static void Run(){"; string po

nginx php动态编译加载模块.

#Nginx动态编译加载模块步骤 #查看目前Nginx版本及编译模块 #[[email protected] ~]# /opt/app/lnmp/nginx-1.12.0/sbin/nginx -V #nginx version: nginx/1.12.0 #built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) #built with OpenSSL 1.0.2k  26 Jan 2017 #TLS SNI support enabled #c

浅谈VB.Net 程序的编译和动态编译

---恢复内容开始--- 一般,我们都是通过Visual Studio(下面简称vs)来编写和编译vb.net应用程序的,但是,不少的人并不知道vs是通过何种方式编译程序的.今天,我们就来探讨一下编译vb.net程序的真正原理. 这篇随笔包含如下几个部分: 1.VS是怎么编译的 2.通过vbc.exe来编译应用程序 3.在代码中通过VBCodeProvider动态编译应用程序 ok,首先来说说vs编译应用程序的方法.其实,vs是通过调用vbc.exe来编译vbnet应用程序的.vs把用户编写的代

动态编译添加php模块

注意:转载请注明出处:http://www.programfish.com/blog/?p=85 在很多时候我们用linux里搭建web服务器的时候会需要编译安装php套件,而在编译安装后可能又会需要添加一些编译安装时没有指定要编译进去的模块,例如如下情况: mysql.so 或mysqli.so .mbstring.so  zlib.so 等模块. 这里提示一下: 如果你有安装过phpmyadmin而且在安装配置好之后打开首页是空白的,那么很有可能就是你的php没有mysql和mbstring

Apache静态编译与动态编译区别

静态编译: 在编译时,已经把相关模块编译进httpd二进制文件中不用再 httpd.conf 中在 LoadModule 来加载,只要在  <ifmodule></ifmodule> 中来配置就可以了. 动态编译: 编译的时候,使用 enable-module=shared  或者 enable-modules-shared=module 来动态编译. 动态显然就不编译到httpd里面去了,启动的时候根本不会加载这个模块, 而是给你一个 module.so  文件.你想用,就在ht