Error using CSharpCodeProvider , is it thread safe?

0

My question is around the .NET 4.6 CSharpCodeProvider class and if it is thread-safe. I have a set of objects based on a FinancvialInstrument class which in turn generates a C# class in order to calculate the value of the financial product. Ideally, we would like to run execution of these generated classes in parallel but when doing so we get an error. The following is the code we use to build and execute the generated class. Source is a string that contains the C# code

public void RunCode(string Source)
{
 var cd = new CSharpCodeProvider();
 CompilerParameters compiler_parameters = new CompilerParameters();
 var exePath = Assembly.GetExecutingAssembly().Location;
 var assemblyFolder = System.Reflection.Assembly.GetAssembly(this.GetType()).CodeBase.ToString();
 assemblyFolder = Path.GetDirectoryName(assemblyFolder);
 assemblyFolder = assemblyFolder.Replace(@"file:\", "");
 var assemRefs = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
 var references = new List<string>();\\
 foreach (var assemblyName in assemRefs)
          references.Add(assemblyName.Name + ".dll");

  foreach (var t in references)
  {
    var localName = Path.Combine(assemblyFolder, t);
              if (File.Exists(localName))
                                compiler_parameters.ReferencedAssemblies.Add(localName);
  }

  compiler_parameters.ReferencedAssemblies.Add(exePath);
  compiler_parameters.GenerateInMemory = true;
  compiler_parameters.GenerateExecutable = false;
  compiler_parameters.GenerateInMemory = true;
  compiler_parameters.IncludeDebugInformation = true;
  compiler_parameters.WarningLevel = 1;
  compiler_parameters.TreatWarningsAsErrors = false;
  compiler_parameters.CompilerOptions = "/optimize";
  var executingAssembly = Assembly.GetExecutingAssembly();
  compiler_parameters.ReferencedAssemblies.Add(executingAssembly.Location);
  CompilerResults compileResults;

  compileResults = cd.CompileAssemblyFromSource(compiler_parameters, Source);

}

When run in a normal for loop as follows

foreach(var source in SourceList).      
       RunCode(source)

all works ok but when we try and execute the code in parallel as

parralell.foreach(SourceList, x => RunCode(x));

we get the following error when calling CompileAssemblyFromSource

System.ArgumentException occurred HResult=0x80070057 Message=The file name 'C:\Users\s.price\AppData\Local\Temp\2\zrnpj1cs.0.cs' was already in the collection. Parameter name: fileName Source=System StackTrace: at System.CodeDom.Compiler.TempFileCollection.AddFile(String fileName, Boolean keepFile) at System.CodeDom.Compiler.TempFileCollection.AddExtension(String fileExtension, Boolean keepFile) at Microsoft.CSharp.CSharpCodeGenerator.FromSourceBatch(CompilerParameters options, String[] sources) at Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromSourceBatch(CompilerParameters options, String[] sources)

It looks to us like the CSharpCodeProvider may not be thread-safe. Is this the case and if so is there an alternative approach to get around this?

Thanks for any help

Regards

Steve

c#
.net
asked on Stack Overflow Nov 4, 2018 by Steven Price • edited Nov 4, 2018 by Llazar

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0