I have a C# application where I spawn multiple threads. I'm on .NET framework 4.7.1. Inside these threads, work is performed and this work may execute user-defined scripted functions. I am using ClearScript as the scripting engine and for purposes of this question I am using the VBScriptEngine. Here is an sample application demonstrating my problem:
static VBScriptEngine vbsengine = new VBScriptEngine();
static void Main(string[] args)
{
for (int i=0;i<4000;i++)
{
Thread t = new Thread(Program.ThreadedFunc);
t.Start(i);
}
Console.ReadKey();
}
static void ThreadedFunc(object i)
{
Console.WriteLine(i + ": " + vbsengine.Evaluate("1+1"));
}
On the Evaluate() function I get the following error: System.InvalidOperationException: 'The calling thread cannot access this object because a different thread owns it.'
I understand ClearScript has implemented thread affinity and a spawned thread cannot access the globally defined engine. So what is my alternative? Create a new instance of ClearScript for each new thread? This seems incredibly wasteful and would create a lot of overhead - my application will need to process thousands of threads. I went ahead and tried this approach anyways - and while it does work (for a while) - end up getting an error. Here's a revised version of my sample app:
static void Main(string[] args)
{
for (int i=0;i<4000;i++)
{
Thread t = new Thread(Program.ThreadedFunc);
t.Start(i);
}
Console.ReadKey();
}
static void ThreadedFunc(object i)
{
using (VBScriptEngine vbsengine = new VBScriptEngine())
{
Console.WriteLine(i + ": " + vbsengine.Evaluate("1+1"));
}
}
On the new VBScriptEngine() call, I now start getting: System.ComponentModel.Win32Exception: 'Not enough storage is available to process this command'.
I'm not really sure what's causing that message as the application isn't taking up a lot of RAM.
I realize this sample application is starting all the threads at once but my full application ensures only 4 threads are running and I still end up getting this message after a while. I don't know why, but I can't get rid of this message either - even after restarting the app and Visual Studio. A little clarity on what's causing this message would be useful.
So my question is - if I only need, say 4 threads, running at once - is there a way I can just create 4 instances of the VBScriptEngine and reuse it for each new thread call? Or even just 1 instance of the VBScriptEngine on the main thread and each new thread just shares it?