Freigeben über


Prozessinterne parallele Ausführung

Hinweis

Dieser Artikel ist spezifisch für .NET Framework. Sie gilt nicht für neuere Implementierungen von .NET, einschließlich .NET 6 und höherer Versionen.

Ab .NET Framework 4 können Sie paralleles Hosting verwenden, um mehrere Versionen der Common Language Runtime (CLR) in einem einzigen Prozess auszuführen. Standardmäßig werden verwaltete COM-Komponenten mit der .NET Framework-Version ausgeführt, mit der sie erstellt wurden, unabhängig von der .NET Framework-Version, die für den Prozess geladen wird.

Hintergrund

Das .NET Framework hat immer paralleles Hosting für Anwendungen mit verwaltetem Code bereitgestellt, aber vor .NET Framework 4 wurde diese Funktionalität für verwaltete COM-Komponenten nicht bereitgestellt. In der Vergangenheit wurden verwaltete COM-Komponenten, die in einen Prozess geladen wurden, entweder mit der Version des bereits geladenen Laufzeitsystems oder mit der neuesten installierten Version von .NET Framework ausgeführt. Wenn diese Version nicht mit der COM-Komponente kompatibel war, schlägt die Komponente fehl.

.NET Framework 4 bietet einen neuen Ansatz für paralleles Hosting, das Folgendes sicherstellt:

  • Die Installation einer neuen Version von .NET Framework hat keine Auswirkungen auf vorhandene Anwendungen.

  • Anwendungen werden für die Version von .NET Framework ausgeführt, mit der sie erstellt wurden. Sie verwenden nicht die neue Version von .NET Framework, es sei denn, sie werden ausdrücklich dazu aufgefordert. Es ist jedoch für Anwendungen einfacher, auf die Verwendung einer neuen Version von .NET Framework umzusteigen.

Auswirkungen auf Benutzer und Entwickler

  • Endbenutzer und Systemadministratoren. Diese Benutzer können jetzt mehr Vertrauen haben, wenn sie eine neue Version der Laufzeit entweder unabhängig oder mit einer Anwendung installieren, hat sie keine Auswirkungen auf ihre Computer. Vorhandene Anwendungen werden weiterhin wie zuvor ausgeführt.

  • Anwendungsentwickler. Paralleles Hosting wirkt sich fast nicht auf Anwendungsentwickler aus. Standardmäßig werden Anwendungen immer für die Version von .NET Framework ausgeführt, auf der sie erstellt wurden; dies hat sich nicht geändert. Entwickler können dieses Verhalten jedoch außer Kraft setzen und die Anwendung unter einer neueren Version von .NET Framework ausführen (siehe Szenario 2).

  • Bibliotheksentwickler und Nutzer. Das parallele Hosting löst nicht die Kompatibilitätsprobleme, die Bibliotheksentwicklern gegenüberstehen. Eine Bibliothek, die direkt durch eine Anwendung geladen wird, entweder durch einen Direktverweis oder einen Assembly.Load-Aufruf, verwendet weiterhin die Runtime von AppDomain, in der sie geladen wurde. Sie sollten Ihre Bibliotheken mit allen Versionen von .NET Framework testen, die Sie unterstützen möchten. Wenn eine Anwendung mit der .NET Framework 4-Laufzeit kompiliert wird, aber eine Bibliothek enthält, die mit einer früheren Laufzeit erstellt wurde, verwendet diese Bibliothek auch die .NET Framework 4-Laufzeit. Wenn Sie jedoch über eine Anwendung verfügen, die mit einer früheren Laufzeit und einer Bibliothek erstellt wurde, die mit .NET Framework 4 erstellt wurde, müssen Sie erzwingen, dass Ihre Anwendung auch .NET Framework 4 verwendet (siehe Szenario 3).

  • Entwickler verwalteter COM-Komponenten. In der Vergangenheit wurden verwaltete COM-Komponenten automatisch mit der neuesten Version der auf dem Computer installierten Laufzeit ausgeführt. Sie können jetzt COM-Komponenten für die Version der Laufzeit ausführen, mit der sie erstellt wurden.

    Wie in der folgenden Tabelle dargestellt, können Komponenten, die mit .NET Framework, Version 1.1 erstellt wurden, parallel mit Version 4-Komponenten ausgeführt werden, aber sie können nicht mit Version 2.0, 3.0- oder 3.5-Komponenten ausgeführt werden, da side-by-side hosting für diese Versionen nicht verfügbar ist.

    .NET Framework-Version 1.1 2.0 - 3.5 4
    1.1 Nicht anwendbar Nein Ja
    2.0 - 3.5 Nein Nicht anwendbar Ja
    4 Ja Ja Nicht anwendbar

Hinweis

.NET Framework-Versionen 3.0 und 3.5 werden inkrementell auf Version 2.0 erstellt und müssen nicht nebeneinander ausgeführt werden. Diese sind inhärent dieselbe Version.

Häufige Parallelhostingszenarien

  • Szenario 1: Systemeigene Anwendung, die COM-Komponenten verwendet, die mit früheren Versionen von .NET Framework erstellt wurden.

    .NET Framework-Versionen installiert: .NET Framework 4 und alle anderen Versionen von .NET Framework, die von den COM-Komponenten verwendet werden.

    Was zu tun ist: Tun Sie in diesem Szenario nichts. Die COM-Komponenten werden mit der Version von .NET Framework ausgeführt, bei der sie registriert wurden.

  • Szenario 2: Verwaltete Anwendung, die mit .NET Framework 2.0 SP1 erstellt wurde, die Sie lieber mit .NET Framework 2.0 ausführen möchten, aber bereit sind, auf .NET Framework 4 auszuführen, wenn Version 2.0 nicht vorhanden ist.

    .NET Framework-Versionen installiert: Eine frühere Version von .NET Framework und .NET Framework 4.

    Was zu tun ist: Verwenden Sie in der Anwendungskonfigurationsdatei im Anwendungsverzeichnis das <startup> Element und das <supportedRuntime> Element wie folgt:

    <configuration>
      <startup >
        <supportedRuntime version="v2.0.50727" />
        <supportedRuntime version="v4.0" />
      </startup>
    </configuration>
    
  • Szenario 3: Systemeigene Anwendung, die COM-Komponenten verwendet, die mit früheren Versionen von .NET Framework erstellt wurden, die Sie mit .NET Framework 4 ausführen möchten.

    .NET Framework-Versionen installiert: .NET Framework 4.

    Was zu tun ist: Verwenden Sie in der Konfigurationsdatei der Anwendung im Anwendungsverzeichnis das <startup>-Element, wobei das useLegacyV2RuntimeActivationPolicy-Attribut auf true festgelegt und das <supportedRuntime>-Element wie folgt eingestellt ist:

    <configuration>
      <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0" />
      </startup>
    </configuration>
    

Beispiel

Im folgenden Beispiel wird ein nicht verwalteter COM-Host veranschaulicht, der eine verwaltete COM-Komponente ausführt, indem er die Version des .NET Framework verwendet, für die die Komponente kompiliert wurde.

Zum Ausführen des folgenden Beispiels kompilieren und registrieren Sie die folgende verwaltete COM-Komponente mithilfe von .NET Framework 3.5. Um die Komponente zu registrieren, klicken Sie im Menü "Projekt" auf "Eigenschaften", klicken Sie auf die Registerkarte "Erstellen", und aktivieren Sie dann das Kontrollkästchen "Für COM-Interoperabilität registrieren".

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);
        }
    }
}

Kompilieren Sie die folgende nicht verwaltete C++-Anwendung, die das COM-Objekt aktiviert, das durch das vorherige Beispiel erstellt wird.

#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;
}

Siehe auch