2009-07-03 10 views
7

私はVB6 dllを呼び出す必要があるマルチスレッドWindowsサービスを実行しています。このVB6 dllに関するドキュメントはありません。このレガシーシステムは非常に重要なビジネスプロセスをサポートしています。マルチスレッドのC#Windowsサービスアプリケーションから呼び出されるVB6 dllをどのように使用できますか?

初めて(1度のスレッド)、このdllは正常に動作します。他のスレッドはアクセスが必要なので、間違った結果を出します。

私が言って1人をお読みください。

をあなたはVB6を使用している場合は、「ただ、一つのことに注意してあなたのスレッドモデル は、あなたがマルチスレッド サービスを実行している場合は、マンションをサポートするために変更する必要がしようとしているVB。 VB6 DLL に呼び出されるスレッドは、DLLと互換性がある必要があります。

チームの別の男が私に、このddlを分離したアプリケーションドメインに入れるというアイディアを与えました。確信はないけど。

マルチスレッドのC#WindowsサービスアプリケーションからVB6 dllを呼び出すにはどうすればいいですか?

+0

最終的な答えを得るには、より多くの情報が必要です。これはCOM +で実行されるかどうか、前者の場合はインプロセスまたはアウトプロセスを実行しますか?どのようにシステムにインストールするのですか?regsvr32または他の方法で? –

+0

みんなのおかげで、私は問題が何かを発見しました。このDLLはVB 6以外のものでは動作しませんでした。内部にバグがあります。サーバー上で英語の地域設定を受け入れないため、ポルトガル語に変更する必要がありました。クライアント言語。 これまでのところ、このレガシーコンポーネントで動作するためにシングルトンパターンとプロキシパターンを使用していますが、現在はうまく機能しています。 –

答えて

2

スレッドが入ってきたら、オブジェクトを保存して後で新しいスレッドに再利用していますか?可能であれば、スレッドごとに新しいオブジェクトを作成してください。私たちは、このような状況で、私たちが使用するデータ層dllを持っています。あるスレッドで接続を作成した場合、別のスレッドから接続を使用することはできません。各スレッドで新しい接続を作成すると、正常に動作します。

オブジェクトの作成が遅い場合は、ThreadPoolクラスとThreadStatic属性を確認してください。スレッドプールは、同じスレッドセットを何度も再利用して作業を行い、ThreadStaticでは、1つのスレッドのみに存在するオブジェクトを作成することができます。例:

[ThreadStatic] 
public static LegacyComObject myObject; 

リクエストが入ると、それをジョブに変換してスレッドプールに入れます。ジョブが開始したら、静的オブジェクトが初期化されているかどうかを確認します。

void DoWork() 
{ 
    if (myObject == null) 
    { 
     // slow intialisation process 
     myObject = New ... 
    } 

    // now do the work against myObject 
    myObject.DoGreatStuff(); 
} 
0

This article on multithreading Visual Basic 6 DLL'sは、いくつかの洞察を提供します。それは言う:

ActiveX DLLプロジェクト マルチスレッドを作成するには、プロジェクトのプロパティ]ダイアログボックスの[全般]タブ 上に所望の スレッドオプションを選択します。

This articleから選択するための3つの可能なモデルがあると言う:

One thread of execution 
Thread pool with round-robin thread assignment 
Every externally created object is on its own thread 

私はデフォルトはone thread of executionで、他の2つのオプションのいずれかを選択する必要があることと仮定します。

0

あなたはこのを見てみたいことがありますlinky

そしてここでは、私の注意を引いたスニペットです:

VB6 COMオブジェクトがSTAオブジェクトである、それは彼らがSTA上で実行しなければならないことを意味糸。 2つのMTAスレッドからオブジェクトの2つのインスタンスを作成しましたが、オブジェクト自体がCOM(OLE)によって作成されたSTA スレッドで実行され、2つのMTAスレッドからのアクセスがマーシャリングおよび同期されます。 それでは、STAとしてスレッドを初期化して、各オブジェクトがマーシャリングなしで自分のSTAスレッドで実行され、 が正常に動作するようにしてください。

とにかく、VBスタイルのCOMオブジェクトは常にSTAです。今すぐアパートメントのマーシャリングとスレッドの切り替えを防ぐために、STAの初期化されたアパートメントに のインスタンスを作成する必要があります。 Mainに[MTAThread]属性を設定すると、MTAとして STAオブジェクトのインスタンスを作成すると、COMが別の(管理されていない)スレッドを作成し、STAとして初期化するときに、これは デフォルトSTAと呼ばれます)、MTAスレッドからのSTAオブジェクトへのすべての呼び出しがマーシャリングされ(スレッドスイッチが発生します)、Idispatchコール はIPマーシャリングの失敗により失敗します。 したがって、互換性のあるマンションのSTA(したがってVB6)オブジェクトを使用することをお勧めします。

1

あなたは、私はVB6のDLLを呼び出す必要があり、マルチスレッドのウィンドウ サービスを実行している

言います。 この VB6 dllに関するドキュメントはありません。このレガシーシステム は、非常に重要なビジネス プロセスをサポートしています。

と同時に、あなたは(1ºスレッド)最初の時点では

を言って、このDLL はうまく実行されます。他のスレッドが アクセスを必要とするため、間違って開始します 結果。

重要なビジネスプロセスをサポートするコードが古く、文書化されておらず、使用されることはなかった方法で使用されているため、管理者はこのエラーを認識しています。 、使用されることが決してテストされなかった。私はそれも以前.NETから使用されることがテストされていないことを賭けましたか?

は、ここに私の提案だが、これは私が実際に実装しました何かに似ています

VB6 DLLがシングルスレッドで呼ばれることを期待しています。 それを失望させないでください!サービスが始まったら、適切なタイプのスレッドを起動してください(私は意図的にそのSTA/MTAのものをすべて忘れてしまったので、私は言うことはできません)。そのスレッドにVB6 DLLへのアクセス要求をキューイングします。そのようなすべてのアクセスを1つのスレッドで処理します。

このように、VB6 DLLに関する限り、実行するためにテストされたとおりに実行されます。


これは私が実装したものと少し異なります。私はWindowsサービスではなく、Webサービスを持っていました。私はVB6ではなくC DLLを持っていましたが、COMではありませんでした。私は、その物へのすべてのアクセスを単一のクラスにリファクタリングした後、パブリックメソッドのそれぞれにロックステートメントを配置します。

+0

私はジョンともっと同意できませんでした。 VB6 DLLは実質的にあなたのためのブラックボックスなので、真実であることが保証されているものに進みます。最高でも、DLLはシングルスレッドアパートメント(STA)スレッドモデルをサポートする予定です。 STA COMオブジェクトを呼び出すときの考慮事項については、MSDNの次のリンクを参照してください。http://msdn.microsoft.com/en-us/library/ms680112(VS.85).aspxバックを最大限に活用するには、アダプタまたはシングルトンを利用して、一度に1つのスレッドへのオブジェクトアクセスを規制するだけです(Johnが示唆したように)。 COM相互運用機能を監視し、.NETからマーシャリングするようにしてください。 –

関連する問題