Vnitroprocesové souběžné provádění
Poznámka:
Tento článek je specifický pro rozhraní .NET Framework. Nevztahuje se na novější implementace .NET, včetně .NET 6 a novějších verzí.
Počínaje rozhraním .NET Framework 4 můžete použít souběžné hostování v procesu ke spuštění více verzí modulu CLR (Common Language Runtime) v jednom procesu. Spravované komponenty modelu COM ve výchozím nastavení běží s verzí rozhraní .NET Framework, se kterou byly vytvořeny, bez ohledu na verzi rozhraní .NET Framework, která je načtena pro tento proces.
Pozadí
Rozhraní .NET Framework vždy poskytovalo souběžné hostování pro aplikace spravovaného kódu, ale před rozhraním .NET Framework 4 neposkytuje tyto funkce pro spravované komponenty MODELU COM. V minulosti běžely spravované komponenty modelu COM načtené do procesu buď s verzí modulu runtime, která už byla načtena, nebo s nejnovější nainstalovanou verzí rozhraní .NET Framework. Pokud tato verze nebyla kompatibilní s komponentou MODELU COM, komponenta by se nezdařila.
Rozhraní .NET Framework 4 poskytuje nový přístup k souběžné hostování, který zajišťuje následující:
Instalace nové verze rozhraní .NET Framework nemá žádný vliv na existující aplikace.
Aplikace běží na verzi rozhraní .NET Framework, pomocí které byly sestaveny. Nepoužívají novou verzi rozhraní .NET Framework, pokud to výslovně nenasměrují. Pro aplikace je ale jednodušší přejít na používání nové verze rozhraní .NET Framework.
Účinky na uživatele a vývojáře
Koncoví uživatelé a správci systému. Tito uživatelé teď můžou mít větší jistotu, že když nainstalují novou verzi modulu runtime nezávisle nebo s aplikací, nebudou mít na své počítače žádný vliv. Stávající aplikace se budou dál spouštět stejně jako předtím.
Vývojáři aplikací. Souběžné hostování nemá téměř žádný vliv na vývojáře aplikací. Ve výchozím nastavení aplikace vždy běží proti verzi rozhraní .NET Framework, na které byly postaveny; to se nezměnilo. Vývojáři ale můžou toto chování přepsat a směrovat aplikaci tak, aby běžela v novější verzi rozhraní .NET Framework (viz scénář 2).
Vývojáři knihovny a spotřebitelé. Souběžné hostování nevyřeší problémy s kompatibilitou, se kterými se vývojáři knihoven setkávají. Knihovna, která je přímo načtena aplikací – buď prostřednictvím přímého odkazu, nebo prostřednictvím Assembly.Load volání – pokračuje v používání modulu runtime, do kterého AppDomain se načte. Knihovny byste měli otestovat ve všech verzích rozhraní .NET Framework, které chcete podporovat. Pokud je aplikace zkompilována pomocí modulu runtime .NET Framework 4, ale obsahuje knihovnu vytvořenou pomocí staršího modulu runtime, bude tato knihovna používat také modul runtime .NET Framework 4. Pokud však máte aplikaci vytvořenou pomocí dřívějšího modulu runtime a knihovny vytvořené pomocí rozhraní .NET Framework 4, musíte vynutit, aby aplikace používala také rozhraní .NET Framework 4 (viz scénář 3).
Vývojáři spravovaných komponent MODELU COM. V minulosti se spravované komponenty modelu COM automaticky spustily pomocí nejnovější verze modulu runtime nainstalovaného v počítači. Nyní můžete spouštět komponenty modelu COM s verzí modulu runtime, pomocí které byly sestaveny.
Jak je znázorněno v následující tabulce, komponenty vytvořené pomocí rozhraní .NET Framework verze 1.1 mohou běžet souběžně s komponentami verze 4, ale nemůžou spouštět s komponentami verze 2.0, 3.0 nebo 3.5, protože pro tyto verze není k dispozici souběžné hostování.
Verze rozhraní .NET Framework 1,1 2.0 - 3.5 4 1,1 Nelze použít No Ano 2.0 - 3.5 No Nelze použít Ano 4 Ano Ano Nelze použít
Poznámka:
Rozhraní .NET Framework verze 3.0 a 3.5 se vytvářejí přírůstkově na verzi 2.0 a nemusí běžet vedle sebe. Jedná se ze své podstaty o stejnou verzi.
Běžné scénáře souběžného hostování
Scénář 1: Nativní aplikace, která používá komponenty MODELU COM vytvořené v dřívějších verzích rozhraní .NET Framework.
Nainstalované verze rozhraní .NET Framework: .NET Framework 4 a všechny ostatní verze rozhraní .NET Framework používané komponentami MODELU COM.
Co dělat: V tomto scénáři nic neudělejte. Komponenty modelu COM se budou spouštět s verzí rozhraní .NET Framework, ve které byly zaregistrovány.
Scénář 2: Spravovaná aplikace vytvořená pomocí rozhraní .NET Framework 2.0 SP1, kterou byste raději spustili s rozhraním .NET Framework 2.0, ale jsou ochotni spustit na rozhraní .NET Framework 4, pokud není k dispozici verze 2.0.
Nainstalované verze rozhraní .NET Framework: Starší verze rozhraní .NET Framework a rozhraní .NET Framework 4.
Akce: V konfiguračním souboru aplikace v adresáři aplikace použijte< spouštěcí> element a podporovanou sadu elementůRuntime><následujícím způsobem:
<configuration> <startup > <supportedRuntime version="v2.0.50727" /> <supportedRuntime version="v4.0" /> </startup> </configuration>
Scénář 3: Nativní aplikace, která používá komponenty modelu COM vytvořené se staršími verzemi rozhraní .NET Framework, které chcete spustit s rozhraním .NET Framework 4.
Nainstalované verze rozhraní .NET Framework: .NET Framework 4.
Akce: V konfiguračním souboru aplikace v adresáři aplikace použijte
<startup>
element s atributemuseLegacyV2RuntimeActivationPolicy
nastaveným natrue
a<supportedRuntime>
element nastaven následujícím způsobem:<configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0" /> </startup> </configuration>
Příklad
Následující příklad ukazuje nespravovaného hostitele modelu COM, který spouští spravovanou komponentu COM pomocí verze rozhraní .NET Framework, kterou byla komponenta zkompilována pro použití.
Pokud chcete spustit následující příklad, zkompilujte a zaregistrujte následující spravovanou komponentu COM pomocí rozhraní .NET Framework 3.5. Chcete-li zaregistrovat součást, klepněte v nabídce Projekt na příkaz Vlastnosti, klepněte na kartu Sestavení a potom zaškrtněte políčko Zaregistrovat pro zprostředkovatele komunikace modelu COM.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace BasicComObject
{
[ComVisible(true), Guid("9C99C4B5-CA54-4c58-8988-49B6811BA53B")]
public class MyObject : SimpleObjectModel.IPrintInfo
{
public MyObject()
{
}
public void PrintInfo()
{
Console.WriteLine("MyObject was activated in {0} runtime in:\n\tAppDomain {1}:{2}", System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion(), AppDomain.CurrentDomain.Id, AppDomain.CurrentDomain.FriendlyName);
}
}
}
Zkompilujte následující nespravovanou aplikaci C++, která aktivuje objekt COM vytvořený předchozím příkladem.
#include "stdafx.h"
#include <string>
#include <iostream>
#include <objbase.h>
#include <string.h>
#include <process.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
char input;
CoInitialize(NULL) ;
CLSID clsid;
HRESULT hr;
HRESULT clsidhr = CLSIDFromString(L"{9C99C4B5-CA54-4c58-8988-49B6811BA53B}",&clsid);
hr = -1;
if (FAILED(clsidhr))
{
printf("Failed to construct CLSID from String\n");
}
UUID id = __uuidof(IUnknown);
IUnknown * pUnk = NULL;
hr = ::CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,id,(void **) &pUnk);
if (FAILED(hr))
{
printf("Failed CoCreateInstance\n");
}else
{
pUnk->AddRef();
printf("Succeeded\n");
}
DISPID dispid;
IDispatch* pPrintInfo;
pUnk->QueryInterface(IID_IDispatch, (void**)&pPrintInfo);
OLECHAR FAR* szMethod[1];
szMethod[0]=OLESTR("PrintInfo");
hr = pPrintInfo->GetIDsOfNames(IID_NULL,szMethod, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
DISPPARAMS dispparams;
dispparams.cNamedArgs = 0;
dispparams.cArgs = 0;
VARIANTARG* pvarg = NULL;
EXCEPINFO * pexcepinfo = NULL;
WORD wFlags = DISPATCH_METHOD ;
;
LPVARIANT pvRet = NULL;
UINT * pnArgErr = NULL;
hr = pPrintInfo->Invoke(dispid,IID_NULL, LOCALE_USER_DEFAULT, wFlags,
&dispparams, pvRet, pexcepinfo, pnArgErr);
printf("Press Enter to exit");
scanf_s("%c",&input);
CoUninitialize();
return 0;
}