Des Suggestions ? Exporter (0) Imprimer
Développer tout
Cet article a fait l'objet d'une traduction manuelle. Déplacez votre pointeur sur les phrases de l'article pour voir la version originale de ce texte. Informations supplémentaires.
Traduction
Source

Développement de composants de flux de données avec plusieurs entrées

 

Un composant de flux de données avec plusieurs entrées peut consommer excessivement de la mémoire si ses entrées multiples produisent des données à des taux irréguliers.Lorsque vous développez un composant de flux de données personnalisé qui prend en charge plusieurs entrées, vous pouvez gérer cette sollicitation de la mémoire en utilisant les membres suivants dans l'espace de noms Microsoft.SqlServer.Dts.Pipeline :

Ces deux membres vous permettent de développer une solution pour la sollicitation de la mémoire qui est semblable à la solution que Microsoft a développée pour les transformations de fusion et de jointure de la fusion.

La première étape pour l'implémentation d'une meilleure gestion de la mémoire pour un composant de flux de données personnalisé qui prend en charge plusieurs entrées consiste à définir la valeur de la propriété P:Microsoft.SqlServer.Dts.Pipeline.DtsPipelineComponentAttribute.SupportsBackPressure à true dans le T:Microsoft.SqlServer.Dts.Pipeline.DtsPipelineComponentAttribute.Lorsque la valeur de P:Microsoft.SqlServer.Dts.Pipeline.DtsPipelineComponentAttribute.SupportsBackPressure est true, le moteur de flux de données appelle la méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.IsInputReady(System.Int32[],System.Boolean[]@) et, lorsqu'il y a plusieurs entrées, il appelle également la méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.GetDependentInputs(System.Int32) au moment de l'exécution.

Dans l'exemple suivant, l'implémentation du T:Microsoft.SqlServer.Dts.Pipeline.DtsPipelineComponentAttribute définit la valeur de P:Microsoft.SqlServer.Dts.Pipeline.DtsPipelineComponentAttribute.SupportsBackPressure à true.

[DtsPipelineComponent(ComponentType = ComponentType.Transform,
        DisplayName = "Shuffler",
        Description = "Shuffle the rows from input.",
        SupportsBackPressure = true,
        LocalizationType = typeof(Localized),
        IconResource = "Microsoft.Samples.SqlServer.Dts.MIBPComponent.ico")
]
public class Shuffler : Microsoft.SqlServer.Dts.Pipeline.PipelineComponent
        {
          ...
        }

Lorsque vous définissez la valeur de la propriété P:Microsoft.SqlServer.Dts.Pipeline.DtsPipelineComponentAttribute.SupportsBackPressure à true dans l'objet T:Microsoft.SqlServer.Dts.Pipeline.DtsPipelineComponentAttribute, vous devez également fournir une implémentation pour la méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.IsInputReady(System.Int32[],System.Boolean[]@) de la classe T:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.

System_CAPS_noteRemarque

Votre implémentation de la méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.IsInputReady(System.Int32[],System.Boolean[]@) ne doit pas appeler les implémentations dans la classe de base.L'implémentation par défaut de cette méthode dans la classe de base lève simplement une NotImplementedException.

Lorsque vous implémentez cette méthode, vous définissez l'état d'un élément dans le tableau canProcess Booléen pour chacune des entrées du composant.(Les entrées sont identifiées par leurs valeurs d'ID dans le tableau inputIDs.) Lorsque vous définissez la valeur d'un élément dans le tableau canProcess à true pour une entrée, le moteur de flux de données appelle la méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.ProcessInput(System.Int32,Microsoft.SqlServer.Dts.Pipeline.PipelineBuffer) du composant et fournit davantage de données pour l'entrée spécifiée.

Si plus de données en amont sont disponibles, la valeur de l'élément de tableau canProcess pour au moins une entrée doit toujours être true, ou traiter les arrêts.

Le moteur de flux de données appelle la méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.IsInputReady(System.Int32[],System.Boolean[]@) avant d'envoyer chaque mémoire tampon de données pour déterminer quelles entrées attendent de recevoir d'autres données.Lorsque la valeur de retour indique qu'une entrée est bloquée, le moteur de flux de données met temporairement en cache les mémoires tampon supplémentaires de données pour cette entrée au lieu de les envoyer au composant.

System_CAPS_noteRemarque

Vous n'appelez pas les méthodes M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.IsInputReady(System.Int32[],System.Boolean[]@) ou M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.GetDependentInputs(System.Int32) dans votre propre code.Le moteur de flux de données appelle ces méthodes, et les autres méthodes de la classe PipelineComponent que vous remplacez, lorsque le moteur de flux de données exécute votre composant.

Dans l'exemple suivant, l'implémentation de la méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.IsInputReady(System.Int32[],System.Boolean[]@) indique qu'une entrée attend pour recevoir plus de données lorsque les conditions suivantes sont remplies :

  • Plus de données en amont sont disponibles pour l'entrée (!inputEOR).

  • Le composant n'a pas actuellement de données disponibles pour traiter l'entrée dans les mémoires tampon que le composant a déjà reçues (inputBuffers[inputIndex].CurrentRow() == null).

Si une entrée attend pour recevoir plus de données, le composant de flux de données indique cela en définissant à true la valeur de l'élément dans le tableau canProcess qui correspond à cette entrée.

Inversement, lorsque le composant a encore des données disponibles à traiter pour l'entrée, l'exemple interrompt le traitement de l'entrée.L'exemple fait cela en définissant à false la valeur de l'élément dans le tableau canProcess qui correspond à cette entrée.

public override void IsInputReady(int[] inputIDs, ref bool[] canProcess)
{
    for (int i = 0; i < inputIDs.Length; i++)
    {
        int inputIndex = ComponentMetaData.InputCollection.GetObjectIndexByID(inputIDs[i]);

        canProcess[i] = (inputBuffers[inputIndex].CurrentRow() == null)
            && !inputEOR[inputIndex];
    }
}

L'exemple précédent utilise le tableau inputEOR booléen pour indiquer si davantage de données en amont sont disponibles pour chaque entrée. EOR dans le nom du tableau représente « fin d'ensemble de lignes » et fait référence à la propriété P:Microsoft.SqlServer.Dts.Pipeline.PipelineBuffer.EndOfRowset de mémoires tampon de flux de données.Dans une partie de l'exemple qui n'est pas inclus ici, la méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.ProcessInput(System.Int32,Microsoft.SqlServer.Dts.Pipeline.PipelineBuffer) vérifie la valeur de la propriété P:Microsoft.SqlServer.Dts.Pipeline.PipelineBuffer.EndOfRowset pour chaque mémoire tampon des données qu'elle reçoit.Lorsqu'une valeur true indique que plus aucune donnée en amont n'est disponible pour une entrée, l'exemple définit la valeur de l'élément de tableau inputEOR pour cette entrée à true.Cette exemple de la méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.IsInputReady(System.Int32[],System.Boolean[]@) définit la valeur de l'élément correspondant dans le tableau canProcess à false pour une entrée lorsque la valeur de l'élément de tableau inputEOR indique qu'aucune donnée en amont n'est disponible pour l'entrée.

Lorsque votre composant de flux de données personnalisé prend en charge plus de deux entrées, vous devez également fournir une implémentation pour la méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.GetDependentInputs(System.Int32) de la classe T:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.

System_CAPS_noteRemarque

Votre implémentation de la méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.GetDependentInputs(System.Int32) ne doit pas appeler les implémentations dans la classe de base.L'implémentation par défaut de cette méthode dans la classe de base lève simplement une NotImplementedException.

Le moteur de flux de données appelle seulement la méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.GetDependentInputs(System.Int32) lorsque l'utilisateur joint plus de deux entrées au composant.Lorsqu'un composant a uniquement deux entrées, et que la méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.IsInputReady(System.Int32[],System.Boolean[]@) indique qu'une entrée est bloquée (canProcess = false), le moteur de flux de données sait que l'autre entrée attend de recevoir plus de données.Toutefois, lorsqu'il y a plus de deux entrées, et que la méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.IsInputReady(System.Int32[],System.Boolean[]@) indique qu'une entrée est bloquée, le code supplémentaire dans le M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.GetDependentInputs(System.Int32) identifie quelles entrées attendent de recevoir plus de données.

System_CAPS_noteRemarque

Vous n'appelez pas les méthodes M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.IsInputReady(System.Int32[],System.Boolean[]@) ou M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.GetDependentInputs(System.Int32) dans votre propre code.Le moteur de flux de données appelle ces méthodes, et les autres méthodes de la classe PipelineComponent que vous remplacez, lorsque le moteur de flux de données exécute votre composant.

Pour une entrée spécifique bloquée, l'implémentation suivante de la méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.GetDependentInputs(System.Int32) retourne une collection des entrées qui attendent de recevoir plus de données et par conséquent bloque l'entrée spécifiée.Le composant identifie les entrées bloquantes en recherchant d'autres entrées que celle qui est bloquée qui n'ont pas actuellement de données disponibles pour traiter dans les mémoires tampon que le composant a déjà reçues (inputBuffers[i].CurrentRow() == null).La méthode M:Microsoft.SqlServer.Dts.Pipeline.PipelineComponent.GetDependentInputs(System.Int32) retourne ensuite la collection d'entrées bloquantes comme une collection d'ID d'entrée.

public override Collection<int> GetDependentInputs(int blockedInputID)
{
    Collection<int> currentDependencies = new Collection<int>();
    for (int i = 0; i < ComponentMetaData.InputCollection.Count; i++)
    {
        if (ComponentMetaData.InputCollection[i].ID != blockedInputID
            && inputBuffers[i].CurrentRow() == null)
        {
            currentDependencies.Add(ComponentMetaData.InputCollection[i].ID);
        }
    }

    return currentDependencies;
}
Afficher:
© 2016 Microsoft