情報: Visual Basic COM + コンポーネントでのグローバル変数を回避します。

文書翻訳 文書翻訳
文書番号: 815053 - 対象製品
この資料は、アーカイブされました。これは "現状のまま" で提供され、更新されることはありません。
すべて展開する | すべて折りたたむ

概要

Visual Basic 6. 0 COM + アパートメント コンポーネントでグローバル変数を使用するとデータが壊れています。 Visual Basic COM + コンポーネントはシングルスレッド アパートメント (STA) スレッドを使用します。 これは、結果、COM + でアクティビティをそのプールの STA スレッドにバインドに使用されるメカニズムのための負荷がかかっている破損データ可能性があります。 Visual Basic COM + コンポーネントでのグローバル変数の使用は推奨しません。

詳細

Visual Basic でのグローバル変数はわずかに異なるスコープ内から C++ プログラムでグローバル変数です。 クラスのすべてのインスタンスを共有するグローバル変数の 1 つのコピー、代わりに、Visual Basic はスレッド ローカル ストレージ (TLS) 各グローバル変数スレッドごとの一意コピーを保存します。 同じ アパートメント クラスの 2 つのインスタンスが複数の STA スレッドにバインドされて場合各 STA (および、そのため、そのクラスのインスタンスを 2 つの各) は、独自のグローバル変数のコピーにします。 各 TLS が、STA. に固有なため、変更によって、値に 1 つのインスタンス (1 つの STA) では表示されずことインスタンス (異なる STA)

COM + で Visual Basic アパートメント コンポーネントを構成する場合は、COM + のアクティビティ モデルが破損するグローバル変数があります。 COM +、負荷に応じて、プールされたその STA スレッドのいずれかに最大 5 つのアクティビティをバインドします。 したがって、実行、または 5 つの呼び出し元の 5 つの異なる論理チェーンすべてにバインドできる 1 つの STA スレッド。

複数のスレッドは、同じ STA で同時に実行できません。 この呼び出しを STA. の非表示のウィンドウに転記される WM_USER メッセージとしてパッケージされて COM メソッドが、STA にバインドされているオブジェクトを呼び出すと、 COM チャネル、送信のアパートメント メソッド呼び出し、またはプロセス間のリモート プロシージャ コール (RPC) が行われると、実際のメソッドを呼び出すさせる別のスレッドを作成し、メッセージ ループに入ります、キュー内の次のメッセージをサービスします。

同時実行に対しては再入に対するしないデータを保護する、STA、あるためそのスレッド上で、2 番目の呼び出し (活動)、CPU の使用および中、最初の呼び出し元は進行中に、グローバル TLS データにアクセスできます。 この 2 つ目の呼び出し元は、preempted の最初の呼び出しが変更された TLS] に同じデータにアクセスします。 2 番目のメッセージが処理中に、データが変更を反映この変更すぐにします。 最初の呼び出しが戻るとき、データが以前に表示内容と異なるありデータが損傷していることを決定が見つかります。

たとえばを COM + では、 MyVBClass というクラスを持つ Visual Basic アパートメント コンポーネントを構成します。 MyVBClass は、グローバル整数変数 g_MyVal を変更するコードを含みます。 呼び出し先元、クライアント X、 MyVBClass のインスタンスを作成し g_MyVal を 5 に設定するメソッドを呼び出します。 同じメソッドでは MyVBClass か、アパートメント間またはプロセス間の RPC 呼び出し別の COM + コンポーネントを実行します。 COM チャネル、実際の RPC 呼び出しに、追加のスレッドを作成し、COM メッセージ ポンプを入力 Y のクライアントからの保留中の呼び出しを処理します。

クライアント Y を 10 に g_MyVal を設定、その作業を完了およびを返します。 Y のクライアントの呼び出しが完了したら、クライアント X の送信メソッド呼び出しは、プロセッサを再度使用してください。 クライアント X 呼び出し g_MyVal を読み取り、それ以前の設定値を受け取る ( 5 )。 ただし、値 10 が受信しました。 クライアント X にこれは破損している値です。

任意のマルチスレッド実行環境では Visual Basic のグローバル関数は、各スレッドの TLS で固有です。 ただし、する COM + 同時実行制御を使用するコンポーネントを明示的に構成する場合を除き、どの STA 上、インスタンスにバインドされます小さなコントロールを持ちます。 ただし、COM + の同時実行のみ保証される実行の同じ論理スレッドですべてのインスタンスが STA にバインド、同じ。 別のスレッドの実行を開始する場合または COM + 使用していない場合、同期、インスタンスが、適切なグローバル表現が格納される STA に連結されていません。 これは別の方法をグローバルを使用する Visual Basic でときに問題が発生できることです。

いない IIS や COM + などの任意のマルチスレッド環境で実行される Visual Basic コンポーネントでグローバル変数を使用操作を行うことお勧めします。 代わりに、クラスのプライベート変数を宣言し、次のサンプル コードのようにパブリック プロパティを使用して公開できます。

グローバル変数の回避策を回避します。

' Private variable for storing the value
Private intMyVal As Integer

' Public property to retrieve the value
Public Property Get MyValue() As Integer
    MyValue = intMyVal
End Property

' Public property to assign the value
Public Property Set MyValue(myVal As Integer)
    intMyVal = myVal
End Property

EmulateMTSBehavior の回避策

この問題を回避するには別の方法は、
EmulateMTSBehavior
レジストリ キーを設定します。 この設定が、独自のスレッド上に作成されるオブジェクトのインスタンス。 したがって、同じ TLS データを共有する 2 つのインスタンスの現象発生できなくします。
メモ
EmulateMTSBehavior
レジストリ キーを使って、100 個のスレッドに到達したら動作から既定の設定に返され、スレッドを再利用できます。

重要です アーキテクチャ、に応じてこのレジストリ キーを設定する可能性がありますパフォーマンスが悪化 COM + アプリケーションの。 このレジストリ キー設定、十分に強調する場合は、アプリケーションのパフォーマンスが許容できることを確認するをテストします。 関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください:
303071COM + のスレッドとアクティビティをチューニングのレジストリ キーの情報:
EmulateMTSBehavior
レジストリ キーを設定する方法の詳細については、次のマイクロソフト Web サイトを参照してください。
http://msdn2.microsoft.com/en-us/library/ms809941.aspx

Visual Basic オブジェクトの組み込み

Visual Basic のコード、 アプリケーション Err 、および プリンター の組み込みの Visual Basic オブジェクトは TLS ではスレッドごとに格納されます。 これらのオブジェクトには TLS への同時アクセス可能性のある問題が発生もします。 COM + やインターネット インフォメーション サービス (IIS) などマルチスレッド分散環境で非常に慎重にこれらのオブジェクトを使用します。

App オブジェクト

アプリケーション オブジェクトには、読み取り専用の情報について、Visual Basic アプリケーションとイベントをログに記録する方法についてが含まれています。 開発者は App.StartLogging メソッドで、イベントは、方法を制御するには、 アプリケーション オブジェクトのプロパティ変更できます、 App.LogEvent メソッドを使用してログに記録します。 イベントを記録すること方法を変更する App.StartLogging を呼び出すときに、グローバルの アプリケーション オブジェクト、そのスレッド上でコンポーネントの各共有されているしたに影響します。 アプリケーションが、 App.StartLogging メソッドを使用して場合、は、正しい logMode App.LogEvent を呼び出すたびに設定するには呼び出すことを確認します。

プリンター オブジェクト

プリンター にグローバル オブジェクトのプロパティを設定すると、更新された新しいデータ使用してそのスレッド上で Visual Basic コンポーネントのすべてのインスタンス。 Visual Basic コンポーネントは、 プリンター のプロパティを変更場合、する必要があります、プロパティ設定いることを確認は正しく印刷する直前にします。 同じスレッドでコンポーネントの別のインスタンスが変更されたオフ、ドキュメントはスプールする時間と、設定された時間の間で、プロパティをプリンターには、 プリンター のプロパティを確認する必要があります。

オブジェクトをエラーします。

VBA は、 Err オブジェクトを使って、ランタイム エラーが、Visual Basic コンポーネントで発生したときにエラー情報を格納します。 Err オブジェクトは、TLS に格納される、ため、同じスレッド上にあるコンポーネントの Err オブジェクトの同じ、コピーを共有します。

Err の使用が完了したことを確認、ブロッキング呼び出しを実行する同じスレッドで別の Visual Basic コンポーネントを許可することがありますをする前にオブジェクト。 加えないで他アウトプロセスの呼び出しは、イベントは発生せず、および、エラー処理ルーチンの Err オブジェクトに既存データを使用したらまたは不適切な結果を取得することがありますまで内から DoEvents を呼び出さないでください。

しないパス Visual 基本コンポーネント外、 Err オブジェクト。 また、 Err オブジェクトはプライベート Visual Basic オブジェクトです。 渡さないでください、外のコンポーネント。 2 番目のオブジェクトは、 Err オブジェクトへのアクセスが、 Err オブジェクト呼び出し戻すを元の Visual Basic コンポーネント データを使用する別の STA 上。 そのデータが現在のオブジェクトの正しくない可能性があります。 エラー情報を渡すと、コンポーネントの外部する必要がある場合、は、 Err.Number Err.Description などの特定のデータを渡します。 詳細については、の次のマイクロソフト Web サイトを参照してください。
http://msdn2.microsoft.com/en-us/library/aa716186(VS.60).aspx

関連情報

関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください:
253744PRB: Visual Basic ことはできませんが使用 COM + を作成するコンポーネントをプールされました。
この資料で説明されている再入問題の詳細については、次のマイクロソフト Web サイトを参照してください。
http://msdn2.microsoft.com/en-us/library/aa261361(VS.60).aspx
COM + のアクティビティの詳細については、次のマイクロソフト Web サイトを参照してください。
http://msdn2.microsoft.com/en-us/library/ms809826.aspx

プロパティ

文書番号: 815053 - 最終更新日: 2014年2月27日 - リビジョン: 4.3
この資料は以下の製品について記述したものです。
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
  • Microsoft Visual Basic 6.0 Learning Edition
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
  • Microsoft Visual Basic 5.0 Learning Edition
キーワード:?
kbnosurvey kbarchive kbinfo kbthread kbcompmodel kbcomapartment kbcomservices kbcomplusobj kbmt KB815053 KbMtja
機械翻訳の免責
重要: このサポート技術情報 (以下「KB」) は、翻訳者による翻訳の代わりに、マイクロソフト機械翻訳システムによって翻訳されたものです。マイクロソフトは、お客様に、マイクロソフトが提供している全ての KB を日本語でご利用いただけるように、翻訳者による翻訳 KB に加え機械翻訳 KB も提供しています。しかしながら、機械翻訳の品質は翻訳者による翻訳ほど十分ではありません。誤訳や、文法、言葉使い、その他、たとえば日本語を母国語としない方が日本語を話すときに間違えるようなミスを含んでいる可能性があります。マイクロソフトは、機械翻訳の品質、及び KB の内容の誤訳やお客様が KB を利用されたことによって生じた直接または間接的な問題や損害については、いかなる責任も負わないものとします。マイクロソフトは、機械翻訳システムの改善を継続的に行っています。
英語版 KB:815053
Microsoft Knowledge Base の免責: Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com