Chyba: AppDomainUnloaded výnimkou keď používate riadené rozšírenia pre súčasti Visual C++

Preklady článku Preklady článku
ID článku: 309694 - Zobraziť produkty, ktorých sa tento článok týka.
Rozbaliť všetko | Zbaliť všetko

Na tejto stránke

PRIZNAKY

Tento problém sa vyskytuje, keď hovor je vyrobená z nespravovaná kód spravovaný kód, vrátane priamych ladom-na-spravovaná hovory v rámci jednej DLL. napríklad, problém môže nastať keď MEC + +/ IJW sa používa v ASP.NET aplikácie. V ASP.NET, rôzne udalosti môže spôsobiť aplikácie sa nastavia do nových AppDomain. Ak používate MEC ++ komponentov a IJW v tomto žiadosť, môže sa zobraziť AppDomainUnloadException chybové hlásenie.

PRICINA

Ako súčasť uskutočňovania IJW, keď spravovaných DLL aby ste vytvorili pomocou c ++ kompilátor bremien, runtime vytvára thunks pre prechody z nespravovaná kódu spravovaný kód. Prvotnú obsahovať odkaz na AppDomain, v ktorom sa načíta DLL. Runtime nie znova vytvoriť prvotnú ak DLL načíta opäť; tiež runtime nie aktualizovať odkaz, keď pôvodný AppDomain uvoľní a DLL načíta do Ďalším AppDomain.

Keď program vykoná prechod od nespravovaná kód spravovaný kód, program používa zastaraný AppDomain odkaz na spustenie spravovaný kód. Aj keď pôvodný AppDomain je stále naložené, kód nemôže získať prístup k statických polí pretože polia sú špecifické pre AppDomain.

RIEŠENIE

Tieto riešenia sú zoskupené podľa dvoch scenáre:
  • Prechod z nespravovaná kód na spravovaný kód cez dva DLL
  • Prechod z nespravovaná kód na spravovaný kód v rovnaké DLL

Nespravovaná kód riadiť kód prechodu cez dva DLL

Použiť niektorú z nasledovných metód na vyriešenie tejto špecifické problém.

Riešenie 1

Pre ASP.NETTO klientov, povoliť ASP.ČISTÝ hostiteľský proces vypnúť Autor: odchytu DomainUnload udalosť. Avšak, musíte sa najskôr zaregistrovať delegátom DomainUnload udalosť. Chcete urobiť, postupujte nasledovne:
  1. V Application_Start metóda ASP.NET Uplatňovanie trieda, register delegát sa nazýva keď AppDomain uvoľní.
  2. V registrovaný delegátom, vypnutie Aspnet_wp.exe proces.
Poznámka Toto riešenie spôsobí všetky ASP.NET aplikácií na počítač reštartujte; údaje o stave v priebehu relácie pre všetky tieto žiadosti sa stratí. V Internet informačnou službou (IIS) 6.0 na počítači so systémom Windows 2003 Server, môžete nakonfigurovať program pre jeden uplatňovanie každého procesu režimu. Ďalšie informácie o configuing aplikácie bazény, navštívte nasledovnú webovú lokalitu spoločnosti Microsoft:
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);
}
				

Riešenie 2

Nahradiť všetky prechody z nespravovaná kódu spravovaný kód s hovory prostredníctvom nespravovaná funkcia ukazovateľa, ktorý vytvoríte pomocou delegát (čo je AppDomain špecifické). Delegát marshaled nespravovaná kódu pomocou platformy Invocation služby)P a vyvolať) namiesto z IJW.

Pre nespravované DLL opísané v "Ďalšie informácie" časti tohto článku, nasledujúci kód vzorky ukazuje, ako používať P a vyvolať použitie spätného volania metódy:
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;
		}
	};
}
				

Nespravovaná kód riadený kód prechodu v rovnakej knižnici DLL

V tomto scenári, môžete mať nespravovaná metódy (označené # pragma ladom) volaním metódy spravovaných zložky v rovnakej knižnici DLL, ako je uvedené v časti "Ďalšie informácie" tohto článku. Použiť niektorú z nasledovných možností metódy tohto špecifického problému:

Riešenie 1

Maršal ukazovateľa funkciu ako delegáta a že použiť Delegát. Pretože nemôžete použiť P a vyvolať na rovnakom DLL, vytvorte wrapper knižnice DLL, ktorá umožňuje maršal delegovať na ukazovateľ funkcie. Tento exportovaná funkcia vráti adresu Delegát, ktoré sú mu postúpené. Nasledujúci kód vzorky je príkladom Toto riešenie:
//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;
}
				
Nasledujúci kód vzorky je pre riadené rozšírenia pre c ++ zhromaždenie, ktoré používa predchádzajúcich 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();
     }
}
				

Riešenie 2

Rozdeliť vaše MEC ++ zhromaždenia do dvoch dll, ten, ktorý obsahuje iba riadené komponenty a iné, ktoré obsahuje iba nespravovaná súčasti, a potom použitie P a vyvolať ako je opísané v riešenie 2 scenár č.1.

STAV

Spoločnosť Microsoft potvrdila, že ide o chybu v programe Microsoft výrobky, ktoré sú uvedené na začiatku tohto článku.

DALSIE INFORMACIE

Problém je viac prevláda ak klient alebo hostiteľa žiadosť musí uvoľniť a načítať AppDomains, a žiadosť obsahuje prechody od nespravovaná kód spravovaný kód používajúce MEC ++ a IJW súčasti. ASP.ČISTÁ je jedným z dobrých príkladov takýchto hostiteľa. V ASP.NET, udalosti že môžu spúšťač AppDomain uvoľniť udalosť môže byť čokoľvek z kríženia pamäť používanie prah dotýka niektorých súborov (napríklad Machine.config).

Kroky na reprodukovanie správanie

V tomto príklade máte ASP.ČISTÝ aplikácia, ktorá vyzýva MEC ++ zložky a tejto zložky má funkcia ukazovateľ, ktorý poukazuje na jeden metód MEC ++ komponentu. Komponent prechádza funkciu Smerník na jedno z nasledujúcich:
  • funkciu, ktorá bol vyvezený nespravovaná knižnica DLL
  • nespravovaná metóda v rovnakej knižnici DLL
Nespravovaná kód potom robí spätné volanie pomocou funkcie ukazovateľa, ktorý bol obdržaný od MEC ++ komponentu.

V nasledujúcich scenáre, je možné, že pred nespravovaná funkcia vyvolá je funkcia ukazovateľ, pôvodné AppDomain, v ktorom bola načítaná DLL vyložený. Za takýchto podmienok nespravovaná kód stále odkazy originálne AppDomain a snaží sa výzva na spravovaný kód v tomto kontexte.
  • Nespravovaná kód riadiť kód prechodu cez dva DLL

    Volať vyvážaných nespravovaná funkcia DLL z MEC ++ zhromaždenia jedným z nasledujúcich spôsobov:
    • pomocou IJW
    • pomocou P a vyvolať
    Nasledujúci kód vzorky používa nespravovaná DLL (Win32.dll) vývoz metódu.
    //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;
    }
    					
    Súprava spravovaných C++ môžu volať touto metódou cez IJW prepojením na Win32.lib a zahrnutím vhodné hlavička súboru. Nasledujúce vzorka kódu ukazuje, ako používať vyvážaných metódu.
    #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;
    		}
    	};
    }
    					
  • Nespravovaná kód riadený kód prechodu v rovnakej knižnici DLL

    V tomto scenári MEC ++ zhromaždenie obsahuje nespravovaná metódy (označené # pragma ladom), vyzvať metód zložky MEC ++ v rovnakej knižnici DLL, ako je uvedené v nasledujúcom kóde vzorky.
    #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();
         }
    }
    					

ODKAZY

Pre viac informácií navštívte nasledujúce Microsoft Developer Network (MSDN) webových lokalít:
Žiadosť domén
http://msdn2.Microsoft.com/en-us/library/cxk374d9 (vs.71) .aspx? rám = true

AppDomain Class
http://msdn2.Microsoft.com/en-us/library/System.appdomain (vs.71) .aspx

AppDomainUnloadedException Class
http://msdn.Microsoft.com/en-us/library/System.appdomainunloadedexception (VS.71) .aspx

Spravovaných rozšírenia pre c ++ programovanie
http://msdn2.Microsoft.com/en-us/library/aa712574 (vs.71) .aspx

Vytvorenie ASP.NET webových aplikácií
http://msdn.Microsoft.com/en-us/library/aa719794.aspx

Pracovník proces izolácia režim
http://www.Microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/34604f82-9175-4d48-b5ea-1e11f19db5f3.mspx?mfr=true

Vlastnosti

ID článku: 309694 - Posledná kontrola: 1. novembra 2011 - Revízia: 2.0
Informácie v tomto článku sa týkajú nasledujúcich produktov:
  • Microsoft Visual C++ .NET 2002 Standard Edition
  • Microsoft .NET Framework 1.0
Kľúčové slová: 
kbbug kbijw kbmanaged kbpending kbmt KB309694 KbMtsk
Strojovo preložené
DÔLEŽITÉ: Tento článok bol preložený pomocou softvéru na strojový preklad od spoločnosti Microsoft, nie prekladateľom. Spoločnosť Microsoft ponúka články preložené prekladateľmi aj strojovo preložené články, vďaka čomu máte možnosť prístupu ku všetkým článkom databázy Knowledge Base vo svojom jazyku. Strojovo preložený článok však nie je vždy perfektný. Môže obsahovať chyby týkajúce sa slovnej zásoby, syntaxe alebo gramatiky, podobne ako cudzinec môže robiť chyby, keď rozpráva vašim jazykom. Spoločnosť Microsoft nenesie zodpovednosť za akékoľvek nepresnosti, chyby alebo škody spôsobené akýmkoľvek nepresným prekladom obsahu alebo jeho použitím zo strany zákazníkov. Spoločnosť Microsoft softvér na strojový preklad pravidelne aktualizuje.
Pokiaľ chcete vidieť anglickú verziu článku, kliknite sem:309694

Odošlite odozvu

 

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