Ejecución en paralelo y en proceso

A partir de .NET Framework versión 4, puede usar el hospedaje en paralelo en el mismo proceso para ejecutar varias versiones de Common Language Runtime (CLR) en un único proceso. De forma predeterminada, los componentes COM administrados se ejecutan con la versión de .NET Framework con la que se compilaron, sin tener en cuenta la versión de .NET Framework que está cargada para el proceso.

Antecedentes

.NET Framework siempre ha proporcionado hospedaje en paralelo para aplicaciones de código administrado, pero antes de .NET Framework 4 no proporcionaba esa funcionalidad para componentes COM administrados. En el pasado, los componentes COM administrados que se cargaban en un proceso se ejecutaban con la versión del runtime que ya estaba cargada o con la última versión instalada de .NET Framework. Si esta versión no era compatible con el componente COM, se producía un error en el componente.

.NET Framework 4 proporciona un nuevo enfoque al hospedaje en paralelo que garantiza lo siguiente:

  • La instalación de una nueva versión de .NET Framework no tiene ningún efecto en las aplicaciones existentes.

  • Las aplicaciones se ejecutan con la versión de .NET Framework con la que se compilaron. No utilizan la nueva versión de .NET Framework a menos que se indique expresamente. Sin embargo, es más fácil para las aplicaciones realizar la transición a una nueva versión de .NET Framework.

Efectos en usuarios y desarrolladores

  • Usuarios finales y administradores del sistema. Estos usuarios ya pueden confiar en que la instalación de una nueva versión del runtime, ya sea de forma independiente o con una aplicación, no tendrá ningún impacto en sus equipos. Las aplicaciones existentes continuarán ejecutándose como lo hacían antes.

  • Desarrolladores de aplicaciones. El hospedaje en paralelo no tiene casi ningún efecto en los desarrolladores de aplicaciones. De forma predeterminada, las aplicaciones se ejecutan siempre con la versión de .NET Framework con la que se compilaron; esto no ha cambiado. Sin embargo, los desarrolladores pueden invalidar este comportamiento y dirigir la aplicación para que se ejecute con una versión más reciente de .NET Framework (vea escenario 2).

  • Desarrolladores de bibliotecas y consumidores. El hospedaje en paralelo no resuelve los problemas de compatibilidad a los que se enfrentan los desarrolladores de bibliotecas. Una biblioteca cargada directamente por una aplicación, mediante una referencia directa o una llamada Assembly.Load, continúa utilizando el runtime de AppDomain en el que está cargada. Debería probar las bibliotecas con todas las versiones de .NET Framework que desee admitir. Si una aplicación está compilada mediante el runtime de .NET Framework 4 pero incluye una biblioteca que se compiló mediante un runtime anterior, esa biblioteca también utilizará el runtime de .NET Framework 4. Sin embargo, si tiene una aplicación que se compiló utilizando un runtime anterior y una biblioteca que se compiló mediante .NET Framework 4, debe forzar a su aplicación a utilizar igualmente .NET Framework 4 (vea escenario 3).

  • Desarrolladores de componentes COM administrados. En el pasado, los componentes COM administrados se ejecutaban automáticamente, mediante la última versión del runtime instalada en el equipo. Ya puede ejecutar los componentes COM con la versión del runtime con la que se compilaron.

    Como se muestra en la siguiente tabla, los componentes que se compilaron con la versión 1.1 de .NET Framework se pueden ejecutar en paralelo con componentes de la versión 4, pero no se pueden ejecutar con componentes de la versión 2.0, 3.0 o 3.5, porque el hospedaje en paralelo no está disponible para esas versiones.

    Versión de .NET Framework

    1.1

    2.0 - 3.5

    4

    1.1

    No es aplicable

    No

    2.0 - 3.5

    No

    No es aplicable

    4

    No es aplicable

NotaNota

Las versiones 3.0 y 3.5 de .NET Framework se compilan de forma incremental en la versión 2.0 y no necesitan ejecutarse en paralelo.Se trata inherentemente de la misma versión.

Escenarios de hospedaje en paralelo comunes

  • Escenario 1: una aplicación nativa que utiliza componentes COM compilados con versiones anteriores de .NET Framework.

    Versiones de .NET Framework instaladas: .NET Framework 4 y todas las demás versiones de .NET Framework utilizadas por los componentes COM.

    Lo que debe hacer: en este escenario, no haga nada. Los componentes COM se ejecutarán con la versión de .NET Framework con la que se registraron.

  • Escenario 2: una aplicación administrada compilada con .NET Framework 2.0 SP1 que prefiere ejecutar con .NET Framework versión 2.0, pero desea ejecutar en .NET Framework 4 si la versión 2.0 no está presente.

    Versiones de .NET Framework instaladas: una versión anterior de .NET Framework y .NET Framework 4.

    Lo que debe hacer: en el archivo de configuración de la aplicación en el directorio de aplicaciones, use el elemento <startup> y el elemento <supportedRuntime> establecidos tal y como se indica a continuación:

    <configuration>
      <startup >
        <supportedRuntime version="v2.0.50727" />
        <supportedRuntime version="v4.0" />
      </startup>
    </configuration>
    
  • Escenario 3: una aplicación nativa que utiliza componentes COM compilados con versiones anteriores de .NET Framework y que desea ejecutar con .NET Framework 4.

    Versiones de .NET Framework instaladas: .NET Framework 4.

    Lo que debe hacer: en el archivo de configuración de la aplicación en el directorio de aplicaciones, use el elemento <startup> con el atributo useLegacyV2RuntimeActivationPolicy establecido en true y el elemento <supportedRuntime> establecido del modo siguiente:

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

Ejemplo

En el siguiente ejemplo se muestra un host COM no administrado que está ejecutando un componente COM administrado mediante la versión de .NET Framework con la que se compiló el componente.

Para ejecutar el ejemplo siguiente, compile y registre el siguiente componente COM administrado mediante .NET Framework versión 3.5. Para registrar el componente, en el menú Proyecto, haga clic en Propiedades, haga clic en la pestaña Compilación y, a continuación, active la casilla Registrar para interoperabilidad 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);
        }
    }
}

Compile la siguiente aplicación C++ no administrada, que activa el objeto COM creado en el ejemplo anterior.

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

Vea también

Referencia

Elemento <startup>

<supportedRuntime> (Elemento)

Historial de cambios

Fecha

Historial

Motivo

Agosto de 2010

Número de versión corregido para .NET Framework 2.0 en el archivo de configuración de la aplicación.

Comentarios de los clientes.