我想從我的常規.NET 3.5應用程序中使用Mono的編譯器作爲服務。單聲道編譯器即服務(MCS)
我已經下載了最新的位(2.6.7),在Visual Studio中創建了一個簡單的控制檯應用程序,並引用了Mono.CSharp dll。
然後,在我的控制檯應用程序(直出樣品在線):
Evaluator.Run("using System; using System.Linq;");
bool ress;
object res;
Evaluator.Evaluate(
"from x in System.IO.Directory.GetFiles (\"C:\\\") select x;",
out res, out ress);
foreach (var v in (IEnumerable)res)
{
Console.Write(v);
Console.Write(' ');
}
這將引發在Evaluator.Run異常(第一行):
Illegal enum value: 2049.
Parameter name: access
這是因爲我相信dll是使用Mono.exe編譯的,而不是csc.exe。
我試過在demo-repl.zip文件中直接從http://tirania.org/blog/archive/2010/Apr-27.html下載Mono.CSharp dll ...並且不會引發異常......但是調用Evaluator.Evaluate之後的out參數(res)是空的...所以我不知道發生了什麼問題。沒有例外拋出...
所以,我想弄清楚爲什麼我從demo-repl.zip下載的DLL返回null。
編輯:我想通了它爲什麼返回null。這似乎是由於某種原因編譯器沒有拿起System.Linq命名空間......雖然我不能說出爲什麼......如果我只是評估「System.IO.Directory.GetFiles(\」C:\\ 「)」,它工作正常。
更新:它看起來像是單引擎編譯器拾取引用的系統程序集有問題。如果我直接在其CSHARP控制檯工具的樣本複製:
csharp> var list = new int [] {1,2,3};
csharp> var b = from x in list
> where x > 1
> select x;
csharp> b;
我得到異常:
{interactive}(1,25): error CS1935: An implementation of `Select' query expressio
n pattern could not be found. Are you missing `System.Linq' using directive or `
System.Core.dll' assembly reference?
此外,爲了使MCS實際上是一個可行的解決方案,我需要修改編譯器,以便它發出一個動態程序集,而不是每次評估調用都發出一個程序集(否則會出現一個主要的內存泄漏,我之前已經用CSharpCodeProvider的形式處理過)。有沒有人知道這將是多麼困難,或者有誰能夠指出我在這個正確的方向?
謝謝。
爲什麼不使用http://msdn.microsoft.com/en-us/library/microsoftoft.csharp.csharpcodeprovider(VS.80).aspx? – Andrey 2010-08-04 15:53:07
CSharpCodeProvider每次編譯都會發出並加載程序集(即使只使用內存中的選項)。我將執行數千次評估,因此會有數千個程序集加載到正在執行的AppDomain中(內存泄漏)。此外,CSharpCodeProvider內部使用csc.exe,這比Reflection.Emit處理器密集得多。在之前的項目中,我使用了CSharpCodeProvider,並在根據程序集數量回收的單獨應用程序域中運行評估,但事實證明這是一個巨大的維護開銷,並且非常容易出錯,所以我想避免這種方法。 – Jeff 2010-08-04 16:03:40
另外,我意識到,默認情況下,MCS在每次評估時也會執行一個程序集,但是由於它在內部依賴於Reflection.Emit,我希望能夠更改該行爲以發送到由AppDomain.DefineDynamicAssembly定義的單個程序集。 – Jeff 2010-08-04 16:05:53