複数のスレッドを生成する C# アプリケーションがあります。私は .NET フレームワーク 4.7.1 を使用しています。これらのスレッド内で作業が実行され、この作業によってユーザー定義のスクリプト関数が実行される場合があります。私は ClearScript をスクリプト エンジンとして使用しており、この質問では VBScriptEngine を使用しています。私の問題を示すサンプルアプリケーションは次のとおりです。
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"));
}
Evaluate()関数で、次のエラーが発生します: System.InvalidOperationException: '別のスレッドが所有しているため、呼び出しスレッドはこのオブジェクトにアクセスできません。
ClearScript がスレッド アフィニティを実装しており、生成されたスレッドがグローバルに定義されたエンジンにアクセスできないことを理解しています。それで、私の代替手段は何ですか?新しいスレッドごとに ClearScript の新しいインスタンスを作成しますか? これは非常に無駄に思え、多くのオーバーヘッドが発生します。私のアプリケーションは何千ものスレッドを処理する必要があります。私は先に進み、とにかくこのアプローチを試しました-そして、それが機能している間(しばらくの間)-最終的にエラーが発生します。サンプル アプリの改訂版は次のとおりです。
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"));
}
}
新しい VBScriptEngine()呼び出しで、System.ComponentModel.Win32Exception : 'このコマンドを処理するのに十分なストレージがありません' というメッセージが表示されるようになりました。
アプリケーションが多くの RAM を占有していないため、このメッセージの原因はよくわかりません。
このサンプル アプリケーションはすべてのスレッドを一度に開始していることに気付きましたが、完全なアプリケーションでは 4 つのスレッドしか実行されておらず、しばらくするとこのメッセージが表示されます。理由はわかりませんが、アプリと Visual Studio を再起動した後でも、このメッセージを取り除くことはできません。このメッセージの原因を少し明確にすることは役に立ちます。
私の質問は、一度に 4 つのスレッドを実行するだけでよい場合、VBScriptEngine の 4 つのインスタンスを作成して、新しいスレッド呼び出しごとに再利用する方法はありますか? それとも、メイン スレッドに VBScriptEngine のインスタンスを 1 つだけ配置し、新しいスレッドごとにそれを共有するだけですか?