Cet article a fait l’objet d’une traduction automatique. Pour afficher l’article en anglais, activez la case d’option Anglais. Vous pouvez également afficher le texte anglais dans une fenêtre contextuelle en faisant glisser le pointeur de la souris sur le texte traduit.
Traduction
Anglais

Lazy<T> classe

 

Date de publication : novembre 2016

Prend en charge l'initialisation tardive.

Espace de noms:   System
Assembly:  mscorlib (dans mscorlib.dll)


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

Paramètres de type

T

Type d’objet initialisé tardivement.

NomDescription
System_CAPS_pubmethodLazy<T>()

Initialise une nouvelle instance de la classe Lazy<T>. Quand l’initialisation tardive se produit, le constructeur par défaut du type cible est utilisé.

System_CAPS_pubmethodLazy<T>(Boolean)

Initialise une nouvelle instance de la classe Lazy<T>. Quand une initialisation tardive se produit, le constructeur par défaut du type cible et le mode d’initialisation spécifié sont utilisés.

System_CAPS_pubmethodLazy<T>(Func<T>)

Initialise une nouvelle instance de la classe Lazy<T>. Quand l’initialisation tardive se produit, la fonction d’initialisation spécifiée est utilisée.

System_CAPS_pubmethodLazy<T>(Func<T>, Boolean)

Initialise une nouvelle instance de la classe Lazy<T>. Quand l’initialisation tardive se produit, la fonction d’initialisation spécifiée et le mode d’initialisation sont utilisés.

System_CAPS_pubmethodLazy<T>(Func<T>, LazyThreadSafetyMode)

Initialise une nouvelle instance de la classe Lazy<T> qui utilise la fonction d’initialisation et le mode de cohérence de thread spécifiés.

System_CAPS_pubmethodLazy<T>(LazyThreadSafetyMode)

Initialise une nouvelle instance de la classe Lazy<T> qui utilise le constructeur par défaut de T et le mode de cohérence de thread spécifié.

NomDescription
System_CAPS_pubpropertyIsValueCreated

Obtient une valeur qui indique si une valeur a été créée pour cette instance de Lazy<T>.

System_CAPS_pubpropertyValue

Obtient la valeur initialisée tardivement de l’instance de Lazy<T> active.

NomDescription
System_CAPS_pubmethodEquals(Object)

Détermine si l'objet spécifié est identique à l'objet actuel.(Hérité de Object.)

System_CAPS_protmethodFinalize()

Autorise un objet à tenter de libérer des ressources et d'exécuter d'autres opérations de nettoyage avant qu'il ne soit récupéré par l'opération garbage collection. (Hérité de Object.)

System_CAPS_pubmethodGetHashCode()

Fait office de fonction de hachage par défaut.(Hérité de Object.)

System_CAPS_pubmethodGetType()

Obtient le Type de l'instance actuelle.(Hérité de Object.)

System_CAPS_protmethodMemberwiseClone()

Crée une copie superficielle du Object actuel.(Hérité de Object.)

System_CAPS_pubmethodToString()

Crée et retourne une représentation sous forme de chaîne de la propriété Lazy<T>.Value pour cette instance.(Remplace Object.ToString().)

Utilisez l'initialisation tardive pour différer la création d'un objet très grand ou gourmand en ressources, ou l'exécution d'une tâche consommatrice en ressources, particulièrement lorsqu'une telle création ou exécution peut ne pas se produire pendant la durée de vie du programme.

Pour préparer l’initialisation tardive, vous créez une instance de Lazy<T>. L’argument de type de la Lazy<T> objet que vous créez Spécifie le type de l’objet que vous souhaitez initialiser tardivement. Le constructeur qui vous permet de créer la Lazy<T> objet détermine les caractéristiques de l’initialisation. L’initialisation tardive se produit la première fois le Lazy<T>.Value propriété est accessible.

Dans la plupart des cas, en choisissant un constructeur dépend de vos réponses aux deux questions :

  • L'objet initialisé en différé sera-t-il accessible par plusieurs threads ? Dans ce cas, le Lazy<T> objet peut créer sur n’importe quel thread. Vous pouvez utiliser un des constructeurs simples dont le comportement par défaut consiste à créer un thread-safe Lazy<T> de l’objet, afin que seule une instance de l’objet instancié tardivement est créée, quel que soit le nombre de threads tentent d’y accéder. Pour créer un Lazy<T> objet qui n’est pas thread-safe, vous devez utiliser un constructeur qui vous permet de spécifier la sécurité des threads.

    System_CAPS_cautionAttention

    Rendre le Lazy<T> objet thread-safe ne protège pas les objets initialisés tardivement. Si plusieurs threads peuvent accéder à l’objet initialisé tardivement, vous devez apporter ses propriétés et méthodes sécurisés pour l’accès multithread.

  • Est-ce-que l'initialisation tardive requiert beaucoup de code, ou l'objet initialisé en différé possède un constructeur par défaut qui effectue le nécessaire et ne lève pas d'exception ? Si vous avez besoin d’écrire du code d’initialisation ou si les exceptions doivent être traitées, utilisez un des constructeurs qui prend une méthode de fabrique. Écrire votre code d’initialisation dans la méthode de fabrique.

Le tableau suivant montre le constructeur à choisir, en fonction de ces deux facteurs :

Objet est accessible par

Si aucun code d’initialisation n’est requis (constructeur par défaut), utilisez

Si le code d’initialisation est requis, utilisez

Plusieurs threads

Lazy<T>()

Lazy<T>(Func<T>)

Un thread

Lazy<T>(Boolean) avec isThreadSafe défini sur false.

Lazy<T>(Func<T>, Boolean) avec isThreadSafe défini sur false.

Vous pouvez utiliser une expression lambda pour spécifier la méthode de fabrique. Cela permet de conserver tout le code d’initialisation dans un seul emplacement. L’expression lambda capture le contexte, y compris tous les arguments que vous passez au constructeur de l’objet initialisés tardivement.

La mise en cache d’exception  lorsque vous utilisez les méthodes de fabrique, les exceptions sont mises en cache. Autrement dit, si la méthode de fabrique lève une heure de l’exception du premier un thread tente d’accéder à la Value propriété de la Lazy<T> de l’objet, la même exception est levée à chaque tentative suivante. Cela garantit que chaque appel à la Value propriété produit le même résultat et évite des erreurs subtiles qui pourraient se poser si différents threads obtiennent des résultats différents. Le Lazy<T> est l’acronyme un système réel T qui sinon aurait été initialisé à un moment antérieur, généralement au démarrage. Un échec à ce point antérieur est généralement irrécupérable. S’il existe un risque potentiel pour une erreur récupérable, nous vous recommandons de créer la logique de nouvelle tentative dans la routine d’initialisation (dans ce cas, la méthode de fabrique), comme vous le feriez si vous n’utilisez pas l’initialisation tardive.

Alternative au verrouillage  dans certaines situations, vous souhaiterez peut-être éviter d’avoir le Lazy<T> comportement de verrouillage par défaut de l’objet. Dans de rares cas, il peut exister des interblocages. Dans ce cas, vous pouvez utiliser la Lazy<T>(LazyThreadSafetyMode) ou Lazy<T>(Func<T>, LazyThreadSafetyMode) constructeur et spécifiez LazyThreadSafetyMode.PublicationOnly. Cela permet la Lazy<T> objet pour créer une copie de l’objet initialisé tardivement dans chacun de plusieurs threads si les threads appellent le Value propriété simultanément. Le Lazy<T> objet garantit que tous les threads utilisent la même instance de l’objet initialisé tardivement et ignore les instances qui ne sont pas utilisés. Par conséquent, le coût de réduire la surcharge de verrouillage est que votre programme peut parfois créer et supprimer des copies supplémentaires d’un objet coûteux. Dans la plupart des cas, il est peu probable. Les exemples pour le Lazy<T>(LazyThreadSafetyMode) et Lazy<T>(Func<T>, LazyThreadSafetyMode) constructeurs illustrent ce comportement.

System_CAPS_importantImportant

Lorsque vous spécifiez PublicationOnly, les exceptions sont jamais mises en cache, même si vous spécifiez une méthode de fabrique.

Constructeurs équivalentes  en plus de permettre l’utilisation de PublicationOnly, Lazy<T>(LazyThreadSafetyMode) et Lazy<T>(Func<T>, LazyThreadSafetyMode) constructeurs peuvent de dupliquer les fonctionnalités d’autres constructeurs. Le tableau suivant indique les valeurs de paramètre qui produisent un comportement équivalent.

Pour créer un Lazy<T> objet

Pour les constructeurs ayant une LazyThreadSafetyMode mode paramètre, la valeur mode à 

Pour les constructeurs qui ont une valeur booléenne isThreadSafe paramètre, la valeur isThreadSafe à

Pour les constructeurs sans paramètres de sécurité du thread

Entièrement à thread-safe ; utilise le verrouillage pour vous assurer qu’un seul thread initialise la valeur.

ExecutionAndPublication

true

Tous les constructeurs de ce type sont complètement thread-safe.

Pas thread-safe.

None

false

Non applicable.

Entièrement à thread-safe ; concurrence de threads pour initialiser la valeur.

PublicationOnly

Non applicable.

Non applicable.

Autres capacités  pour plus d’informations sur l’utilisation de Lazy<T> avec les champs thread-static ou comme magasin de stockage pour les propriétés, consultez Lazy Initialization.

L’exemple suivant illustre l’utilisation de la Lazy<T> classe pour fournir l’initialisation tardive avec accès depuis plusieurs threads.

System_CAPS_noteRemarque

L’exemple utilise le Lazy<T>(Func<T>) constructeur. Il illustre également l’utilisation de la Lazy<T>(Func<T>, Boolean) constructeur (spécifiant true pour isThreadSafe) et le Lazy<T>(Func<T>, LazyThreadSafetyMode) constructeur (spécifiant LazyThreadSafetyMode.ExecutionAndPublication pour mode). Pour basculer vers un autre constructeur, modifiez simplement les constructeurs sont commentées.

Pour obtenir un exemple illustrant l’exception, la mise en cache à l’aide des constructeurs de mêmes, consultez le Lazy<T>(Func<T>) constructeur.

L'exemple définit une classe LargeObject qui sera initialisée tardivement par l'un des nombreux threads. Les quatre principales sections de code illustrent la création de l’initialiseur, la méthode de fabrique, l’initialisation réelle et le constructeur de la LargeObject classe, qui affiche un message lorsque l’objet est créé. Au début de la méthode Main, l'exemple crée l'initialiseur de type lazy thread-safe pour 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);

La méthode de fabrique illustre la création de l’objet, avec un espace réservé pour une initialisation supplémentaire :

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

Notez que les sections de deux premiers code peuvent être combinées à l’aide d’une fonction lambda, comme indiqué ici :

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

L’exemple suspend, pour indiquer qu’une période indéterminée peut s’écouler avant que l’initialisation tardive se produit. Lorsque vous appuyez sur la entrée clé, l’exemple crée et démarre trois threads. Le ThreadProc méthode qui est utilisée par tous les appels de trois threads le Value propriété. La première fois dans ce cas, le LargeObject instance est créée :

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

Le constructeur de la LargeObject classe, qui inclut la dernière section clée du code, affiche un message et enregistre l’identité du thread lors de l’initialisation. La sortie du programme s’affiche à la fin de la liste de code complète.

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

Pour plus de simplicité, cet exemple utilise une instance globale de Lazy<T> et toutes les méthodes sont static (Shared en Visual Basic). Ce ne sont pas des exigences pour l’utilisation de l’initialisation tardive.

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
 */

Plateforme Windows universelle
Disponible depuis 8
.NET Framework
Disponible depuis 4.0
Bibliothèque de classes portable
Pris en charge dans : plateformes .NET portables
Silverlight
Disponible depuis 4.0
Silverlight pour Windows Phone
Disponible depuis 8.0
Windows Phone
Disponible depuis 8.1

Par défaut, tous les membres publics et protégés de la Lazy<T> classe sont thread-safe et peuvent être utilisés simultanément par plusieurs threads. Ces garanties de sécurité des threads peuvent être éventuellement supprimées par instance, à l’aide des paramètres pour les constructeurs du type.

Retour au début
Afficher: