Exportar (0) Imprimir
Expandir todo
Este artículo proviene de un motor de traducción automática. Mueva el puntero sobre las frases del artículo para ver el texto original. Más información.
Traducción
Original

Lazy<T> (Clase)

Proporciona compatibilidad con la inicialización diferida.

Espacio de nombres:  System
Ensamblado:  mscorlib (en mscorlib.dll)

[SerializableAttribute]
[ComVisibleAttribute(false)]
[HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true, 
	ExternalThreading = true)]
public class Lazy<T>

Parámetros de tipo

T

El tipo de objeto que se inicializa de forma diferida.

El tipo Lazy<T> expone los siguientes miembros.

  NombreDescripción
Método públicoCompatible con Biblioteca de clases portableCompatible con .NET para aplicaciones de la Tienda WindowsLazy<T>()Inicializa una nueva instancia de la clase Lazy<T>. Cuando se produce la inicialización diferida, se usa el constructor predeterminado del tipo de destino.
Método públicoCompatible con Biblioteca de clases portableCompatible con .NET para aplicaciones de la Tienda WindowsLazy<T>(Boolean)Inicializa una nueva instancia de la clase Lazy<T>. Cuando se produce la inicialización diferida, se usan el constructor predeterminado del tipo de destino y el modo de inicialización especificado.
Método públicoCompatible con Biblioteca de clases portableCompatible con .NET para aplicaciones de la Tienda WindowsLazy<T>(Func<T>)Inicializa una nueva instancia de la clase Lazy<T>. Cuando se produce la inicialización diferida, se usa la función de inicialización especificada.
Método públicoCompatible con Biblioteca de clases portableCompatible con .NET para aplicaciones de la Tienda WindowsLazy<T>(LazyThreadSafetyMode)Inicializa una nueva instancia de la clase Lazy<T> que usa el constructor predeterminado de T y el modo de seguridad para subprocesos especificado.
Método públicoCompatible con Biblioteca de clases portableCompatible con .NET para aplicaciones de la Tienda WindowsLazy<T>(Func<T>, Boolean)Inicializa una nueva instancia de la clase Lazy<T>. Cuando se produce la inicialización diferida, se usan la función de inicialización y el modo de inicialización especificados.
Método públicoCompatible con Biblioteca de clases portableCompatible con .NET para aplicaciones de la Tienda WindowsLazy<T>(Func<T>, LazyThreadSafetyMode)Inicializa una nueva instancia de la clase Lazy<T> que utiliza la función de inicialización y el modo de seguridad para subprocesos especificados.
Arriba

  NombreDescripción
Propiedad públicaCompatible con Biblioteca de clases portableCompatible con .NET para aplicaciones de la Tienda WindowsIsValueCreatedObtiene un valor que indica si se ha creado un valor para esta instancia de Lazy<T>.
Propiedad públicaCompatible con Biblioteca de clases portableCompatible con .NET para aplicaciones de la Tienda WindowsValueObtiene el valor inicializado de forma diferida de la instancia actual de Lazy<T>.
Arriba

  NombreDescripción
Método públicoCompatible con Biblioteca de clases portableCompatible con .NET para aplicaciones de la Tienda WindowsEquals(Object)Determina si el objeto especificado es igual al objeto actual. (Se hereda de Object).
Método protegidoCompatible con Biblioteca de clases portableCompatible con .NET para aplicaciones de la Tienda WindowsFinalize Permite que un objeto intente liberar recursos y realizar otras operaciones de limpieza antes de ser reclamado por la recolección de elementos no utilizados. (Se hereda de Object).
Método públicoCompatible con Biblioteca de clases portableCompatible con .NET para aplicaciones de la Tienda WindowsGetHashCode Sirve como una función hash para un tipo en particular. (Se hereda de Object).
Método públicoCompatible con Biblioteca de clases portableCompatible con .NET para aplicaciones de la Tienda WindowsGetType Obtiene el Type de la instancia actual. (Se hereda de Object).
Método protegidoCompatible con Biblioteca de clases portableCompatible con .NET para aplicaciones de la Tienda WindowsMemberwiseClone Crea una copia superficial del Object actual. (Se hereda de Object).
Método públicoCompatible con Biblioteca de clases portableCompatible con .NET para aplicaciones de la Tienda WindowsToStringCrea y devuelve una representación de cadena de la propiedad Lazy<T>.Value de esta instancia. (Invalida a Object.ToString()).
Arriba

Utilice la inicialización diferida para aplazar la creación de un objeto grande o requerir la utilización, o ejecución de una tarea que requiere, especialmente cuando tal creación o ejecución no aparezca durante la duración del programa.

Para prepararse para la inicialización diferida, se crea una instancia de Lazy<T>. El argumento de tipo del objeto Lazy<T> que cree especifica el tipo del objeto que desea inicializar Lazy. El constructor que utiliza para crear el objeto Lazy<T> determina las características de inicialización. La inicialización no expansiva se produce la primera vez que se tiene acceso a la propiedad Lazy<T>.Value.

En la mayoría de los casos, elegir un constructor depende de las respuestas a dos preguntas:

  • ¿El objeto Lazy inicializado tendrá acceso de varios subprocesos? Si es así el objeto Lazy<T> podría hacerlo en cualquier subproceso. Puede utilizar uno de los constructores simples cuyo comportamiento predeterminado consiste en crear un objeto Lazy<T> seguro para subprocesos, para crear una instancia del objeto Lazy creado instancias independientemente de cómo intento de muchos subprocesos para tener acceso. Para crear un objeto Lazy<T> que no es seguro para subprocesos, debe utilizar un constructor que permite no especificar ninguna seguridad para subprocesos.

    Nota de precauciónPrecaución

    Crear el objeto Lazy<T> para subprocesos no protege el objeto Lazy inicializado. Si varios subprocesos pueden tener acceso al objeto Lazy inicializado, debe crear sus propiedades y métodos seguros para el acceso multiproceso.

  • ¿La inicialización diferida requiere mucho código, o el objeto Lazy inicializado tiene un constructor predeterminado que haga todo lo que necesita y no produce excepciones? Si necesita escribir código de inicialización o si las excepciones es necesario administradas, use uno de los constructores que toma un método de generador. Escriba el código de inicialización del método generador.

La tabla siguiente muestra qué constructor que elegir, en función de estos dos factores:

El objeto se tiene acceso mediante

Si no se requiere ningún código de inicialización (constructor predeterminado), utilice

Si se requiere el código de inicialización, use

Varios subprocesos

Lazy<T>()

Lazy<T>(Func<T>)

Un subproceso

Lazy<T>(Boolean) con isThreadSafe establecido en false.

Lazy<T>(Func<T>, Boolean) con isThreadSafe establecido en false.

Puede usar una expresión lambda para especificar el método de generador. Esto mantiene todo el código de inicialización de uno título. La expresión lambda captura el contexto, incluido cualquier argumento que se pasa al constructor del objeto Lazy inicializado.

El almacenamiento en caché de excepciones  Cuando utilice métodos de generador, se almacenan en caché las excepciones. Es decir, si el método generador produce una excepción la primera vez los intentos de un subproceso para tener acceso a la propiedad Value del objeto Lazy<T> , la misma excepción se produce en cada intento subsiguiente. Esto garantiza que cada llamada a la propiedad Value genera el mismo resultado y evitar errores sutiles que podrían surgir diferentes subprocesos obtienen resultados diferentes. Lazy<T> reemplaza T real que se habría inicializado de otra forma de algún punto anterior, normalmente durante el inicio. Un error en ese punto anterior normalmente es grave. Si hay un potencial de un error recuperable, recomendamos se especificó la lógica Try a la rutina de inicialización (en este caso, el método generador), exactamente igual que si no utilizaba la inicialización diferida.

Alternativa a bloquear  En algunas situaciones, puede ser conveniente evitar la sobrecarga de Lazy<T> comportamiento predeterminado del objeto. En alguna ocasión, puede haber un potencial de los interbloqueos. En tales casos, puede usar el constructor Lazy<T>(LazyThreadSafetyMode) o Lazy<T>(Func<T>, LazyThreadSafetyMode) , y especificar LazyThreadSafetyMode.PublicationOnly. Esto permite al objeto Lazy<T> para crear una copia del objeto Lazy inicializado en cada uno de varios subprocesos si los subprocesos denomina propiedad Value simultáneamente. El objeto Lazy<T> garantiza que todos los subprocesos utilicen la misma instancia de objeto Lazy inicializado y descarta instancias no se utilizan. Así, el costo de reducir la sobrecarga de bloqueo es que el programa puede crear y descartar a veces las copias adicionales de un objeto costoso. En la mayoría de los casos, es improbable. Los ejemplos de los constructores Lazy<T>(LazyThreadSafetyMode) y Lazy<T>(Func<T>, LazyThreadSafetyMode) ilustran este comportamiento.

Nota importanteImportante

Cuando especifica PublicationOnly, las excepciones no se almacenan en caché, incluso si especifica un método de generador.

Constructores equivalentes  Además de habilitar el uso de PublicationOnly, Lazy<T>(LazyThreadSafetyMode) y Lazy<T>(Func<T>, LazyThreadSafetyMode) constructores pueden duplicar la funcionalidad de los otros constructores. La tabla siguiente muestra los valores de parámetro que generan comportamiento equivalente.

Para crear un objeto Lazy<T> que es

Para constructores con un parámetro LazyThreadSafetyMode mode , establezca mode en

Para los constructores que tienen un parámetro booleano isThreadSafe , establezca isThreadSafe en

Para los constructores sin parámetros de seguridad para subprocesos

Totalmente seguro para subprocesos; utiliza el bloqueo para garantizar que inicializa sólo un subproceso el valor.

ExecutionAndPublication

true

Todos esos constructores son segura para subprocesos.

No es seguro para subprocesos.

None

false

No es aplicable

Totalmente seguro para subprocesos; los subprocesos se precipitan a inicializar el valor.

PublicationOnly

No es aplicable

No es aplicable

Otras capacidades  Para obtener información sobre el uso de Lazy<T> con campos subprocesos estáticos, o como memoria auxiliar para las propiedades, vea Inicialización diferida.

NotaNota

El atributo HostProtectionAttribute aplicado a este tipo o miembro tiene el siguiente valor de propiedad Resources: Synchronization | ExternalThreading. El atributo HostProtectionAttribute no afecta a las aplicaciones de escritorio (que normalmente se inician haciendo doble clic en un icono, escribiendo un comando o introduciendo una dirección URL en el explorador). Para obtener más información, vea la clase HostProtectionAttribute o Programación en SQL Server y atributos de protección de host.

El siguiente ejemplo muestra el uso de la clase Lazy<T> para proporcionar la inicialización diferida con acceso desde varios subprocesos.

NotaNota

El ejemplo utiliza el constructor Lazy<T>(Func<T>) . También muestra el uso del constructor Lazy<T>(Func<T>, Boolean) (especificando true para isThreadSafe) y el constructor Lazy<T>(Func<T>, LazyThreadSafetyMode) (especificando LazyThreadSafetyMode.ExecutionAndPublication para mode). Para cambiar a otro constructor, simplemente cambio que comentan los constructores out.

Para obtener un ejemplo que muestre el almacenamiento en caché de excepciones utilizando los mismos constructores, vea el constructor Lazy<T>(Func<T>) .

El ejemplo define una clase LargeObject que uno de varios subprocesos inicializará de forma diferida. Las cuatro secciones clave de código muestran la creación de inicializadores, el método de generador, de inicialización real, y el constructor de la clase LargeObject , que muestra un mensaje cuando se cree. Al principio del método Main, el ejemplo crea el inicializador diferido seguro para subprocesos para LargeObject:


lazyLargeObject = new Lazy<LargeObject>(InitLargeObject);

// The following lines show how to use other constructors to achieve exactly the
// same result as the previous line: 
//lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, true);
//lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, 
//                               LazyThreadSafetyMode.ExecutionAndPublication);


El método generador muestra la creación de objetos, con un marcador para la inicialización:

Observe que las primeras dos secciones de código se pueden combinar mediante una función lambda, como se muestra aquí:


lazyLargeObject = new Lazy<LargeObject>(() => 
{
    LargeObject large = new LargeObject(Thread.CurrentThread.ManagedThreadId);
    // Perform additional initialization here.
    return large;
});


Las pausas de ejemplo, indicar que un período indeterminado puede transcurrir antes de que la inicialización diferida aparezca. Si presiona la tecla Entrar , el ejemplo crea e inicia tres subprocesos. El método ThreadProc utilizado por los tres subprocesos llamadas la propiedad Value . La primera vez que esto sucede, se crea la instancia LargeObject :


LargeObject large = lazyLargeObject.Value;

// IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
//            object after creation. You must lock the object before accessing it,
//            unless the type is thread safe. (LargeObject is not thread safe.)
lock(large)
{
    large.Data[0] = Thread.CurrentThread.ManagedThreadId;
    Console.WriteLine("Initialized by thread {0}; last used by thread {1}.", 
        large.InitializedBy, large.Data[0]);
}


El constructor de la clase LargeObject , que incluye la sección clave pasada de código, muestra un mensaje y registra la identidad del subproceso que inicializa. El resultado del programa aparece al final de la lista de código completa.


int initBy = 0;
public LargeObject(int initializedBy)
{
    initBy = initializedBy;
    Console.WriteLine("LargeObject was created on thread id {0}.", initBy);
}


NotaNota

Por simplificar, en este ejemplo se emplea una instancia global de Lazy<T> y todos los métodos son static (Shared en Visual Basic). No son requisitos para el uso de la inicialización diferida.


using System;
using System.Threading;

class Program
{
    static Lazy<LargeObject> lazyLargeObject = null;

    static LargeObject InitLargeObject()
    {
        LargeObject large = new LargeObject(Thread.CurrentThread.ManagedThreadId);
        // Perform additional initialization here.
        return large;
    }


    static void Main()
    {
        // The lazy initializer is created here. LargeObject is not created until the 
        // ThreadProc method executes.
        lazyLargeObject = new Lazy<LargeObject>(InitLargeObject);

        // The following lines show how to use other constructors to achieve exactly the
        // same result as the previous line: 
        //lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, true);
        //lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, 
        //                               LazyThreadSafetyMode.ExecutionAndPublication);


        Console.WriteLine(
            "\r\nLargeObject is not created until you access the Value property of the lazy" +
            "\r\ninitializer. Press Enter to create LargeObject.");
        Console.ReadLine();

        // Create and start 3 threads, each of which uses LargeObject.
        Thread[] threads = new Thread[3];
        for (int i = 0; i < 3; i++)
        {
            threads[i] = new Thread(ThreadProc);
            threads[i].Start();
        }

        // Wait for all 3 threads to finish. 
        foreach (Thread t in threads)
        {
            t.Join();
        }

        Console.WriteLine("\r\nPress Enter to end the program");
        Console.ReadLine();
    }


    static void ThreadProc(object state)
    {
        LargeObject large = lazyLargeObject.Value;

        // IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
        //            object after creation. You must lock the object before accessing it,
        //            unless the type is thread safe. (LargeObject is not thread safe.)
        lock(large)
        {
            large.Data[0] = Thread.CurrentThread.ManagedThreadId;
            Console.WriteLine("Initialized by thread {0}; last used by thread {1}.", 
                large.InitializedBy, large.Data[0]);
        }
    }
}

class LargeObject
{
    public int InitializedBy { get { return initBy; } }

    int initBy = 0;
    public LargeObject(int initializedBy)
    {
        initBy = initializedBy;
        Console.WriteLine("LargeObject was created on thread id {0}.", initBy);
    }

    public long[] Data = new long[100000000];
}

/* This example produces output similar to the following:

LargeObject is not created until you access the Value property of the lazy
initializer. Press Enter to create LargeObject.

LargeObject was created on thread id 3.
Initialized by thread 3; last used by thread 3.
Initialized by thread 3; last used by thread 4.
Initialized by thread 3; last used by thread 5.

Press Enter to end the program
 */


.NET Framework

Compatible con: 4.5.2, 4.5.1, 4.5, 4

.NET Framework Client Profile

Compatible con: 4

Biblioteca de clases portable

Compatible con: Biblioteca de clases portable

.NET para aplicaciones de la Tienda Windows

Compatible con: Windows 8

.NET para aplicaciones de Windows Phone

Compatible con: Windows Phone 8, Silverlight 8.1

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (no se admite el rol Server Core), Windows Server 2008 R2 (se admite el rol Server Core con SP1 o versiones posteriores; no se admite Itanium)

.NET Framework no admite todas las versiones de todas las plataformas. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

De manera predeterminada, todos los miembros públicos y protegidos de la clase Lazy<T> son seguros para subprocesos y se pueden usar simultáneamente desde varios subprocesos. Estas garantías de seguridad de los subprocesos pueden eliminarse, opcionalmente y por instancia, utilizando parámetros a constructores de tipo.

Adiciones de comunidad

AGREGAR
Mostrar:
© 2014 Microsoft