BUG: AppDomainUnloaded 例外を使用すると Visual C コンポーネントの拡張の管理

文書翻訳 文書翻訳
文書番号: 309694
すべて展開する | すべて折りたたむ

目次

現象

アンマネージ コードからの呼び出しが行われたときにこの問題が発生します。マネージ コードにアンマネージからマネージへの直接の呼び出しを含むDLL。 たとえば、この問題が発生するとき MEC + + IJW で ASP を使用します。NETアプリケーションです。ASP では。NET では、さまざまなイベントを再ロードするのには、アプリケーションを可能性があります。新しいアプリケーション ドメインにします。MEC はコンポーネントおよび IJW で使用する場合アプリケーションは、可能性がありますが、 AppDomainUnloadException エラー メッセージです。

原因

IJW を使用するときに、マネージ DLL の実装の一部としてC++ コンパイラのロードを使用して作成、ランタイムがサンクを作成遷移をアンマネージ コードからマネージ コードにします。これらのサンクが含まれています、DLL の読み込みの AppDomain を参照します。ランタイムはありません。これらサンク再作成するは、DLL の読み込みを再試行した場合です。また、ランタイムはありません。参照元の AppDomain がアンロードされ、DLL の読み込み時に更新します。別のアプリケーション ドメイン。

プログラムからの移行を実行した場合アンマネージ コードをマネージ コードには、AppDomain が古いプログラムを使用してください。マネージ コードを実行するには、[参照] をクリックします。元の AppDomain があってフィールドが固有であるために、コードの静的フィールド アクセスできません。アプリケーション ドメイン。

回避策

以下の回避策 2 に従ってグループ化されていますシナリオ:
  • アンマネージ コードからマネージ コードに 2 つへの移行Dll
  • アンマネージ コードからマネージ コードへの移行、同じ DLL

アンマネージ コードに全体の 2 つの Dll のコードへの移行の管理

このを解決するのには、次の方法のいずれかを使用してください。問題があります。

回避策 1

ASP。クライアントは、asp net を使用できます。NET のホスト プロセスがシャット ダウンするトラッピングでは、 DomainUnload イベントです。ただし、最初のデリゲートを登録する必要があります、 DomainUnload イベントです。これを行うには、次の手順を実行します。
  1. で、 Application_Start ASP の方法です。NET アプリケーション クラス、ときに呼び出されるデリゲートを登録しますアプリケーション ドメイン。アンロードします。
  2. 登録されているデリゲートでは、Aspnet_wp.exe ダウンをシャット ダウンします。プロセスです。
メモ この回避策は、ASP のすべてが発生します。NET アプリケーションでは、コンピューターを再起動します。イン プロセス セッション状態データをすべてアプリケーションは、失われます。インターネット情報サービス (IIS) 6.0 コンピューターWindows Server 2003 が実行されているのいずれか、プログラムを構成することができます。アプリケーションごとの処理モードです。詳細についてはアプリケーションの configuingプールは、次のマイクロソフト Web サイトを参照してください。
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/2a231dcb-d786-4b6d-b3ba-bda04061a5e7.mspx?mfr=true
//Register a delegate to be called when the DomainUnload event fires.
protected void Application_Start(Object sender, EventArgs e)
{
     AppDomain.CurrentDomain.DomainUnload+= new EventHandler(ADUnloading);
}

//This method is called when the AppDomain is about to unload.
public void ADUnloading(object s, EventArgs e)
{
     System.Environment.Exit(0);
}
				

回避策 2

マネージ コードをアンマネージ コードからすべての遷移を交換してください。デリゲートを使用して作成、アンマネージ関数ポインターを通じて呼び出し(アプリケーション ドメイン固有です)。デリゲートをアンマネージ コードにマーシャ リングされます。プラットフォーム呼び出しサービス (を使用してP/起動) IJW ではなく。

アンマネージ DLL の説明については、次のサンプル コードは、この資料の「関連情報」セクション使用する方法を示しています。 P/起動 コールバック メソッドを使用するのには
using namespace System::Runtime::InteropServices; // For DllImportAttribute.

namespace ManagedLib
{
        //Managed delegate declaration.
	public __delegate int ManagedFuncDelg();
	public __gc class Class1
	{
		
	public:
		[DllImport("Win32.dll", EntryPoint="callback")]//Assumes that you have a DEF file for the exports.
		static int Mgdcallback(ManagedFuncDelg*);
                //This method is called from the unmanaged DLL.
		static int InternalMethod()
		{
			return 123;
		}

		static ManagedFuncDelg* pd = new ManagedFuncDelg(0, &ManagedLib::Class1::InternalMethod);

                //This method is called by the client application.
		int Func()
		{
			int ret = ManagedLib::Class1::Mgdcallback(ManagedLib::Class1::pd);
			return ret;
		}
	};
}
				

アンマネージ コードに同じ DLL のコードへの移行を管理

このシナリオでは、(マークのアンマネージ メソッドを持つことができます。 アンマネージ #pragma) に示すように、同じ DLL のマネージ コンポーネントにメソッドを呼び出すこの資料の「関連情報」セクションでします。次のいずれかを使用します。この問題を解決する方法。

回避策 1

関数ポインターとしてのデリゲートのマーシャ リングし、は、使用してくださいデリゲート。使用できないため P/起動 同じ DLL の DLL をマーシャ リングするためのラッパーを作成します。関数ポインターとしてのデリゲートします。このエクスポートされた関数のアドレスを返しますデリゲートに渡されます。サンプル コードを次の例に示しますこの回避策は。
//This is the helper DLL that enables you to marshal the delegate.
//Helper.cpp.
//Helper DLL code.
extern "C" __declspec(dllexport) void* __stdcall FuncInUmDll(void* pv)
{
	return pv;
}
				
次のサンプル コードは、Managed Extensions for C++ です。前の Helper.dll を使用するアセンブリ。
#using <mscorlib.dll>
using namespace System;
using namespace System::Runtime::InteropServices; // for DllImportAttribute

namespace ManagedLib
{
      //Forward declaration.
      __delegate int delg();
      int nativefunc(int(__stdcall*)());
      [System::Runtime::InteropServices::DllImport("helper.dll", EntryPoint="FuncInUmDll")] int FuncInUmDll(delg*);
      //Managed component.
      public __gc class Class1{
	public:
            static int InternalMethod()
            {
                 return 123;
            }

            //This method is called by the client application.
            int Func()
            {
                 delg* d= new delg(0, &Class1::InternalMethod);
                 int ret = nativefunc((int(__stdcall*)())FuncInUmDll(d));
                 return ret;
            }
      };


      #pragma unmanaged
     //Unmanaged function calling the managed delegate.
     int nativefunc(int(__stdcall*pf)())
     {
            return pf();
     }
}
				

回避策 2

MEC はアセンブリだけが含まれている、2 つの Dll に分割します。マネージ コンポーネントとアンマネージ コンポーネントのみを含むし、切り捨てを避けるためには 15 文字以内の名前を使ってください P/起動 回避策 1 のシナリオ 2 の手順に従って。

状況

マイクロソフトは、これは、Microsoft のバグであること確認していますこの資料の冒頭に記載する製品を指定します。

詳細

この問題がより一般的だ場合は、ホストまたはクライアントアプリケーションをアンロードして Appdomain を再読み込みする必要があり、アプリケーションが含まれています。MEC は、IJW を使用してマネージ コードへの遷移アンマネージ コードからコンポーネントです。ASP。NET のようなホストの 1 つの良い例です。ASP では。NET では、イベントイベント トリガーは、アプリケーション ドメインをアンロードできることから横断できる、特定のファイル (たとえば、Machine.config) に触れるには、使用率の閾値をメモリします。

現象の再現手順

この例では、ASP があります。NET アプリケーションを呼び出す、MEC はコンポーネント、およびコンポーネントが 1 つに指す関数ポインターMEC はコンポーネント内のメソッドの。コンポーネント、関数に渡す次のいずれかへのポインター。
  • アンマネージ DLL によってエクスポートされた関数
  • 同じ DLL のアンマネージ メソッド
アンマネージ コードが関数を使用してコールバックにMEC はコンポーネントから受け取ったポインターです。

次シナリオが可能ですが、アンマネージ関数を呼び出す前に、関数ポインターは、元の AppDomain で DLL が読み込まれたです。アンロードします。アンマネージ コードがこのような状況を参照、元の AppDomain としようとするために呼び出すそのコンテキスト内のコードを管理します。
  • アンマネージ コードに全体の 2 つの Dll のコードへの移行の管理

    MEC はからは、アンマネージ DLL のエクスポート関数を呼び出すアセンブリには、次の方法のいずれか。
    • IJW を使用して
    • 使用して P/起動
    次のサンプル コードは、アンマネージ DLL (Win32.dll) を使用してください。そのメソッドをエクスポートします。
    //Win32.h.
    #ifdef WIN32_EXPORTS
    #define WIN32_API __declspec(dllexport)
    #else
    #define WIN32_API __declspec(dllimport)
    #endif
    
    //Declaration.
    typedef int (__stdcall *funcptr)(void);
    WIN32_API int __stdcall  callback(funcptr ptr);
    
    //Win32.cpp Implementation.
    //This method is called by the Managed C++ component either by using P/Invoke
    //or by using IJW.
    WIN32_API int __stdcall callback(funcptr ptr)
    {
    	int rtn= ptr();
    	return rtn;
    }
    					
    マネージ C++ アセンブリにリンクすることによりこのメソッドでは、IJW を呼び出すことができます。Win32.lib は、し適切なヘッダー ファイルをインクルードします。次に、サンプル コードは、エクスポートされたメソッドを使用する方法を示しています。
    #pragma once
    #include "win32.h"
    #using <mscorlib.dll>
    using namespace System;
    
    namespace ManagedLib
    {
    
    	public __gc class Class1
    	{
    		
    	public:
    		static int InternalMethod()
    		{
    			return 123;
    		}
    
                    //This method is called by the client application.
    		int Func()
    		{
    			int ret = callback((funcptr)Class1::InternalMethod);
    			return ret;
    		}
    	};
    }
    					
  • アンマネージ コードに同じ DLL のコードへの移行を管理

    このシナリオでは、MEC はアセンブリが含まれているアンマネージ(表示方法 アンマネージ #pragma) は、呼び出すメソッド MEC は部品が同じ DLL にように次のサンプル コードでは。
    #using <mscorlib.dll>
    using namespace System;
    namespace ManagedLib
    {
          //Forward declararion
          int nativefunc(int(__stdcall*)());
          //Managed component
          public __gc class Class1{
    
    	public:
    
                static int InternalMethod()
                {
                     return 123;
                }
                //This method is called by the client application.
                int Func()
                {
                     int ret = nativefunc((int(__stdcall*)())Class1::InternalMethod);
                     return ret;
                }
          };
    
          #pragma unmanaged
         //Unmanaged function calling the managed delegate.
         int nativefunc(int(__stdcall*pf)())
         {
                return pf();
         }
    }
    					

関連情報

詳細については、以下を参照してください。開発者 (MSDN) Web サイト。
アプリケーション ドメイン
http://msdn2.microsoft.com/en-us/library/cxk374d9 (vs.71) .aspx? フレーム = true

AppDomain クラス
.aspx の http://msdn2.microsoft.com/en-us/library/system.appdomain (vs.71)

AppDomainUnloadedException クラス
.aspx の http://msdn.microsoft.com/en-us/library/system.appdomainunloadedexception (VS.71)

Managed Extensions for C++ のプログラミング
.aspx の http://msdn2.microsoft.com/en-us/library/aa712574 (vs.71)

ASP を作成します。Net
http://msdn.microsoft.com/en-us/library/aa719794.aspx

ワーカー プロセス分離モード
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/34604f82-9175-4d48-b5ea-1e11f19db5f3.mspx?mfr=true

プロパティ

文書番号: 309694 - 最終更新日: 2011年7月24日 - リビジョン: 6.0
キーワード:?
kbbug kbijw kbpending kbmanaged kbmt KB309694 KbMtja
機械翻訳の免責
重要: このサポート技術情報 (以下「KB」) は、翻訳者による翻訳の代わりに、マイクロソフト機械翻訳システムによって翻訳されたものです。マイクロソフトは、お客様に、マイクロソフトが提供している全ての KB を日本語でご利用いただけるように、翻訳者による翻訳 KB に加え機械翻訳 KB も提供しています。しかしながら、機械翻訳の品質は翻訳者による翻訳ほど十分ではありません。誤訳や、文法、言葉使い、その他、たとえば日本語を母国語としない方が日本語を話すときに間違えるようなミスを含んでいる可能性があります。マイクロソフトは、機械翻訳の品質、及び KB の内容の誤訳やお客様が KB を利用されたことによって生じた直接または間接的な問題や損害については、いかなる責任も負わないものとします。マイクロソフトは、機械翻訳システムの改善を継続的に行っています。
英語版 KB:309694
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