ASP.NET MVC Web サイトをサード パーティの COM アプリケーションと統合する必要があります。コードは次のようになります。
Type type = Type.GetTypeFromProgID(progID);
dynamic obj = Activator.CreateInstance(type);
if (!obj.DBOpenedStatus)
{
obj.InitApplicationContext();
//do stuff with other COM objects
}
問題は、しばらくすると、COMExceptions
おそらくobj.ReleaseApplicationContext()
. IDisposable
そのため、コンストラクターでコンテキストを初期化し、破棄されたときにそれを解放できるように実装するラッパーを作成することを考えています。しかしlock
、現在のスレッドがまだ機能している間に別のスレッドがコンテキストを閉じないようにする必要があります。コードは次のようになります。
lock (_locker)
{
using (MyComContextWrapper comContext = new MyComContextWrapper())
{
//do stuff with other COM objects
}
}
私はスレッドセーフについてほとんど知らないので、あなたに尋ねているのは次のとおりです。
- 私のアプローチに何か問題がありますか?
- 他に考慮すべきことはありますか (デッドロックなど)?
- 別のアプローチをお勧めしますか?
編集 1:
レジストリで COM クラスの progID を調べたところThreadingModel=Apartment
、COM アプリケーションがSingle-Threaded Apartment
型を使用していることがわかりました。
編集 2:
COM アプリケーションは、システムを使用してオブジェクトの ID を生成するため、これらのオブジェクトがデータベースに永続化されると、それらのオブジェクトは既に ID を持っています。このシステムには、レジストリにいくつかの情報を書き込むことが含まれます。しばらくすると、このシステムで問題が発生し、violation of primary key constraint
エラーが発生し始めます。
編集 3
: System.ArgumentNullException: Value cannot be null. Parameter name: type at Activator.CreateInstance(Type type)
. これは、別のスレッドから新しい STA オブジェクトを作成しようとしていることが原因でしょうか?
編集 4:
の完全なスタック全体を投稿するように誰かに頼まれましたがCOMExceptions
、これにより私の質問がローカライズされすぎて、私以外の誰にとっても役に立たなくなるのではないかと心配しています。さらに、実際に問題の原因を突き止めました。com オブジェクトを使用する前にコンテキストが初期化されず、システムが混乱する非常にまれなケースがいくつかありましたが、エラーは後でしか表示されませんでした。そのため、com オブジェクトを使用する前にコンテキストが常に初期化されるようにすると、問題は解決しました。
スレッドセーフと提案されたソリューションに関する回答にまだ興味があります。それとも、あまりにもローカライズされているため、質問を閉じる必要がありますか?