L'index interne DataTable est corrompu

je travaille avec une application .net WinForms en C#, qui fonctionne avec le framework 3.5 .net. Dans cette application, je suis en train de le .L'Expression de membre de un DataColumn dans un DataTable , comme suit:

DataColumn column = dtData.Columns["TestColumn"];
column.Expression = "some expression";

la deuxième ligne, où j'ai mis Expression , donnera parfois l'exception suivante:

FileName=
LineNumber=0
Source=System.Data
TargetSite=Int32 RBInsert(Int32, Int32, Int32, Int32, Boolean)
System.InvalidOperationException: DataTable internal index is corrupted: '5'.
   at System.Data.RBTree`1.RBInsert(Int32 root_id, Int32 x_id, Int32 mainTreeNodeID, Int32 position, Boolean append)
   at System.Data.RBTree`1.RBInsert(Int32 root_id, Int32 x_id, Int32 mainTreeNodeID, Int32 position, Boolean append)
   at System.Data.Index.InitRecords(IFilter filter)
   at System.Data.Index.Reset()
   at System.Data.DataTable.ResetInternalIndexes(DataColumn column)
   at System.Data.DataTable.EvaluateExpressions(DataColumn column)
   at System.Data.DataColumn.set_Expression(String value)

il n'y a pas de rime ou de raison perceptible quant au moment où l'erreur se produira; en chargeant le même ensemble de données, il peut travailler bien, mais puis recharger il échouera, et vice versa. Cela me porte à penser qu'il est lié à une condition de course, où une autre opération d'écriture se produit sur le DataTable que je suis en train d'essayer de modifier une de ses colonnes. Cependant, le code relatif à DataTable s est et non multi-threadé et ne fonctionne que sur le filetage UI.

j'ai cherché sur le web et forums Microsoft , et il ya beaucoup de discussion et de confusion autour de cette question. À l'époque où le problème a été signalé pour la première fois en 2006, on pensait qu'il s'agissait d'un défaut dans le cadre .NET, et il y a eu des correctifs supposés qui ont probablement été incorporés dans des versions ultérieures du cadre .NET. Cependant, les gens ont rapporté des résultats mitigés dans l'application de ces correctifs, qui ne sont plus applicables au cadre actuel.

une autre théorie dominante est qu'Il ya des opérations sur le DataTable qui, bien que apparemment inoffensif, sont en fait écrire des opérations. Par exemple, créer un nouveau DataView basé sur un DataTable est en fait une opération d'écriture sur la table elle-même, parce qu'il crée un index interne dans le DataTable pour référence ultérieure. Ces opérations d'écriture ne sont pas sans fil, de sorte qu'il arrive parfois qu'une condition de course mène à une écriture sans fil coïncidant avec notre accès au DataTable . Cela, à son tour, provoque l'index interne du DataTable pour devenir corrompu, conduisant à l'exception.

j'ai essayé de mettre lock blocs autour de chaque DataView création dans le code, mais, comme je l'ai mentionné avant, le code utilisant le DataTable n'est pas fileté, et le lock s n'a pas d'effet, dans tous les cas.

quelqu'un A vu cela et résolu avec succès / travaillé autour d'elle?


non, malheureusement je ne peux pas. Le chargement du DataTable a déjà se produit au moment où je mets la main dessus pour appliquer une Expression à une de ses Datacolumn's. Je pourrais supprimer la colonne et ensuite la rajouter en utilisant le code que vous avez suggéré, mais y a-t-il une raison particulière pour laquelle cela résoudrait le problème de l'index interne corrompu?

25
demandé sur casperOne 2009-01-16 18:09:37

17 réponses

je viens d'avoir le même problème lors de l'importation de lignes, comme il semble, appelant DataTable.BeginLoadData avant que l'insert fixé pour moi.

Edit: Comme il s'avère, ce n'fixé sur un côté, maintenant, l'ajout de lignes lève cette exception.

Edit2: la Suspension de la liaison comme suggéré par Robert Rossney correction de l'ajout de problème pour moi, trop. J'ai simplement enlevé le DataSource du DataGridView et l'a lu après que j'ai été fait avec le DataTable .

Edit 3: toujours pas fixé...l'exception ne cesse de s'insinuer dans tous les endroits de mon code depuis jeudi...c'est de loin le bogue le plus étrange et le plus f***ing que j'ai rencontré dans le cadre jusqu'à présent (et j'ai vu beaucoup de choses étranges dans les 3 années que j'ai travaillé avec .NET 2.0, assez pour garantir que pas un seul de mes futurs projets ne sera construit sur elle). Mais assez de râles, de nouveau sur le sujet.

j'ai lu toute la discussion sur les forums de soutien de Microsoft et je vais vous en donner un bref résumé. Le rapport de bogue original commence en '05 .

  • Mars ' 06: Bug est signalé la première fois, l'enquête commence. Tout au long de l'année prochaine il est rapporté dans différentes formes et différentes manifestations.
  • March '07: enfin un hotfix avec le numéro KB 932491 est publié (ne vous emballez pas), il se lie contre un téléchargement d'un hotfix tout à fait hors de propos , ou du moins il semble. Au cours des prochains mois , de nombreux rapports que le hotfix ne fonctionne pas , certains font état de succès.
  • July '07: dernier signe de live de Microsoft (avec une réponse complètement inutile), au-delà de ce point n'est plus de réponse de Microsoft. Pas d'autres confirmations, pas de tentatives de soutien, Pas de demandes d'informations supplémentaires...rien. Au-delà de ce point, il n'y a que des informations concernant la communauté.

Non sérieusement, cela résume à mon avis. J'ai été en mesure d'extraire les éléments suivants information tirée de l'ensemble de la discussion:

  • le DataTable est et non . Vous aurez à Lock / Synchronize il sur votre propre si vous avez Multi-filetage n'importe où sur elle.
  • la corruption de l'index se produit quelque part avant l'exception réelle est jetée.
  • L'une des sources possibles de corruption est soit une application Expression ou une application Sort .
  • une autre source possible est l'événement DataTable.ListChanged() , ne modifiez jamais les données dans cet événement ou tout autre événement qui se produit à partir de celui-ci. Cela inclut différents événements Changed des contrôles liés.
  • il y a des problèmes possibles lorsque le DefaultView est lié à un contrôle. Toujours utiliser DataTable.BeginLoadData() et DataTable.EndLoadData() .
  • création et manipulation du DefaultView est une opération d'écriture sur le DataTable (et son Index ), le monstre spaghetti volant sait pourquoi.

la source possible de ceci est très probablement une condition de race, soit dans notre code source ou dans le code du cadre. Il semble que Microsoft est incapable de corriger ce bug ou n'a pas l'intention de. De toute façon, vérifiez votre code pour les conditions de course, il a quelque chose à voir avec le DefaultView à mon avis. À un moment donné un Insert ou une manipulation des données corrompt L'indice interne parce que les changements ne sont pas correctement propagés à travers l'ensemble DataTable .

je ferai bien sûr un rapport quand je trouverai d'autres informations ou des corrections supplémentaires. Et désolé si j'ai un peu émotif ici, mais j'ai passé trois jours à essayer de cerner cette question, et il commence doucement à ressembler à une bonne raison pour obtenir un nouvel emploi.

Edit 4: j'ai pu éviter cela bug en supprimant complètement la liaison ( control.DataSource = null; ) et de le rajouter après le chargement des données est terminée. Ce qui alimente ma pensée qu'il a quelque chose à voir avec le DefaultView et les événements qui surgissent des contrôles liés.

17
répondu Bobby 2017-05-23 11:47:01

personnellement, ce bug particulier a été mon ennemi pendant 3 semaines de différentes façons. Je l'ai résolu dans une partie de ma base de code et il apparaît ailleurs (je crois que je l'ai finalement écrasé ce soir). L'information d'exception est plutôt inutile, et un moyen de forcer un reindex aurait été une fonctionnalité agréable étant donné le manque de MS pour résoudre le problème.

Je ne chercherais pas le hotfix DE MS -- ils ont un article de KB dessus, puis vous rediriger vers un ASP.Net c'est totalement indépendants.

OK-assez de plaintes. Voyons ce qui m'a réellement aidé à résoudre ce problème particulier dans les divers endroits où je l'ai rencontré:

  • éviter d'utiliser des vues par défaut, et modifier la vue par défaut si possible. Btw, .Net 2.0 a un certain nombre de serrures de lecteur/écrivain sur la création de vues, de sorte qu'ils ne sont pas la question qu'ils étaient pré 2.0.
  • Appel AcceptChanges() lorsque cela est possible.
  • faites attention .Select (expression), puisqu'il n'y a pas de serrure de lecteur/écrivain dans ce code -- et c'est le seul endroit (au moins selon une personne sur le usenet alors prenez-le avec un grain de sel -- cependant, c'est très similaire à votre problème -- donc utiliser des Mutex peut aider)
  • fixe AllowDBNull à la colonne en question (valeur douteuse, mais rapporté sur l'usenet -- je l'ai utilisé seulement dans les endroits où il a du sens)
  • assurez-vous que vous ne positionnent pas null (C#) / Nothing (VB) sur un champ de DataRow. Utilisez DBNull.Valeur au lieu de null. Dans votre cas, vous pouvez vérifier que le champ n'est pas null, la syntaxe d'expression does supporte l'opérateur IsNull(val, alt_val).
  • cela m'a probablement aidé le plus (aussi absurde que cela puisse paraître): si une valeur ne change pas, ne l'assignez pas. Alors dans votre utilisez ceci à la place de votre affectation pure et simple:

    si (colonne.Expression != "expression") de colonne.Expression = "expression";

(j'ai enlevé les crochets, ne sais pas pourquoi ils étaient là).

Edit (5/16/12): vient de tomber dans ce numéro à plusieurs reprises (avec un UltraGrid/UltraWinGrid). Utilisé le Conseil de supprimer le tri sur le DataView, puis a ajouté une colonne triée qui correspondait au tri DataView, et cela résolu question.

10
répondu torial 2012-05-16 22:12:53

vous mentionnez "pas threadsafe". Manipulez-vous l'objet à partir de différents fils? Si oui, alors qui pourrait très bien être la raison de la corruption.

3
répondu Lasse Vågsæther Karlsen 2009-01-17 16:19:26

Juste une remarque pour ceux qui essaient de voir comment ce bug peut être reproduit. J'ai un code qui produit assez souvent cette erreur. Il fait verrouillage autour de lecture/écriture simultanées, mais l'appel à DataView.FindRows est fait en dehors de ce verrouillage. L'OP a souligné que la création de une vue de données était une opération d'écriture cachée,la questionner aussi?

//based off of code at http://support.microsoft.com/kb/932491
using System.Data;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using System;
public class GenerateSomeDataTableErrors
{   
    public static void Main()
    {
        DataTable Table = new DataTable("Employee");
        Table.Columns.Add("Id", typeof(int));
        Table.Columns.Add("Name", typeof(string));
        Table.PrimaryKey = new DataColumn[] { Table.Columns["Id"] };

        DataSet Employees = new DataSet();
        Employees.Tables.Add(Table);

        DataRow ManagerB = Table.NewRow();
        ManagerB["ID"] = 392;
        ManagerB["Name"] = "somename";
        Table.Rows.Add(ManagerB);

        DataRow ManagerA = Table.NewRow();
        ManagerA["ID"] = 394;
        ManagerA["Name"] = "somename";
        Table.Rows.Add(ManagerA);

        Employees.AcceptChanges();

        object locker = new object();

        //key = exception string, value = count of exceptions with same text
        ConcurrentDictionary<string, int> exceptions = new ConcurrentDictionary<string, int>();

        DataView employeeNameView = new DataView(Table, string.Empty, "Name", DataViewRowState.CurrentRows);

        Parallel.For(0, 100000, (i, s) =>
        {
            try
            {
                #region do modifications to the table, in a thread-safe fashion
                lock (locker)
                {
                    var row = Table.Rows.Find(392);

                    if (row != null) //it's there, delete it
                    {
                        row.Delete();
                        Employees.AcceptChanges();
                    }
                    else //it's not there, add it
                    {
                        var newRow = Table.NewRow();
                        newRow["ID"] = 392;
                        newRow["Name"] = "somename";
                        Table.Rows.Add(newRow);
                        Employees.AcceptChanges();
                    }
                }
                #endregion

                //Apparently this is the dangerous part, finding rows 
                // without locking on the same object the modification work is using.
                //lock(locker)
                employeeNameView.FindRows("somename");
            }
            catch (Exception e)
            {
                string estring = e.ToString();
                exceptions.TryAdd(estring, 0);
                lock (exceptions)
                { exceptions[estring] += 1; }
            }
        });

        foreach (var entry in exceptions)
        {
            Console.WriteLine("==============The following occurred " + entry.Value + " times");
            Console.WriteLine(entry.Key);
        }
    }//Main
}//class

si vous l'exécutez tel quel, vous pouvez obtenir une sortie comme celle-ci (la sortie diffère un peu à chaque fois que vous l'exécutez):

==============The following occurred 2 times
System.InvalidOperationException: DataTable internal index is corrupted: '13'.
   at System.Data.RBTree`1.GetNodeByIndex(Int32 userIndex)
   at System.Data.DataView.GetRow(Int32 index)
   at System.Data.DataView.GetDataRowViewFromRange(Range range)
   at System.Data.DataView.FindRowsByKey(Object[] key)
   at GenerateSomeDataTableErrors.<>c__DisplayClass9.<Main>b__8(Int32 i, ParallelLoopState s) in Program.cs:line 110
==============The following occurred 3 times
System.IndexOutOfRangeException: Index 1 is either negative or above rows count.
   at System.Data.DataView.GetRow(Int32 index)
   at System.Data.DataView.GetDataRowViewFromRange(Range range)
   at System.Data.DataView.FindRowsByKey(Object[] key)
   at GenerateSomeDataTableErrors.<>c__DisplayClass9.<Main>b__8(Int32 i, ParallelLoopState s) in line 110
==============The following occurred 1 times
System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Data.DataView.GetRow(Int32 index)
   at System.Data.DataView.GetDataRowViewFromRange(Range range)
   at System.Data.DataView.FindRowsByKey(Object[] key)
   at GenerateSomeDataTableErrors.<>c__DisplayClass9.<Main>b__8(Int32 i, ParallelLoopState s) in Program.cs:line 110
Press any key to continue . . .

et si vous mettez le verrou sur L'appel FindRows, pas d'exception.

3
répondu Anssssss 2012-08-14 21:29:31

D'après ce que j'ai compris, après avoir longuement et douloureusement marchandé sur ce problème, c'est qu'il s'agit d'un artéfact des opérations d'écriture sans fil, que d'habitude vous ne saviez pas que vous faisiez.

dans mon cas, le coupable semblait être la source. J'ai trouvé que j'avais besoin de suspendre la reliure, effectuer n'importe quelle opération que j'essayais, et puis reprendre la reliure quand j'ai été fait, et le problème a disparu. C'était il y a 18 mois, donc je ne suis plus claire sur les détails, mais Je me souviens avoir eu l'impression que la source de BindingSource faisait une sorte d'opération sur son propre fil. (Cela a moins de sens pour moi maintenant que cela n'en avait à l'époque.)

une autre source potentielle de problème est L'événement de changement de ligne du DataTable. Si vous faites quelque chose qui modifie la table dans ce gestionnaire d'événements, attendez-vous à de mauvaises choses.

2
répondu Robert Rossney 2009-03-19 18:18:18

même problème ici, et essayé une approche différente. Je n'utilise pas le datatable pour des choses liées à l'écran (par exemple la liaison); je crée juste des objets DataRow (dans plusieurs threads) et je les ajoute à la table.

j'ai essayé d'utiliser lock(), et j'ai aussi essayé de centraliser l'ajout des rangs dans un singleton, pensant que cela aiderait. Il ne l'a pas fait. Pour référence, voici le singleton que j'ai utilisé. Peut-être que quelqu'un d'autre sera en mesure de construire sur ce point et figure quelque chose?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace EntityToDataSet
{
   public class RowAdder
   {
      #region Data
      private readonly object mLockObject = new object();
      private static RowAdder mInstance;

      public static RowAdder Instance
      {
         get
         {
            if (mInstance == null)
            {
               mInstance = new RowAdder();
            }
            return mInstance;
         }
      }

      object mSync;
      #endregion

      #region Constructor
      private RowAdder()
      {
      }
      #endregion

      public void Add(DataTable table, DataRow row)
      {
         lock (mLockObject)
         {
            table.Rows.Add(row);
         }
      }
   }
}
1
répondu David Catriel 2011-05-18 20:53:05

Que diriez-vous d'essayer l'idée d'appliquer un mutex comme décrit ici pour induire le sommeil dans le thread dans de telles conditions?

1
répondu Suj 2011-11-14 13:58:10

Voici comment j'ai corrigé mon index interne est corrompu problème:

System.Data.DataTable dtNew = new DataTable();
for (int iCol = 0; iCol < dtOriginalData.Columns.Count; iCol++)
{
    dtNew.Columns.Add(dtOriginalData.Columns[iCol].ColumnName, dtOriginalData.Columns[iCol].DataType);
}
for (int iCopyIndex = 0; iCopyIndex < item.Data.Rows.Count; iCopyIndex++)
{
    dtNew.Rows.Add(dtOriginalData.Rows[iCopyIndex].ItemArray);
    //dtNew.ImportRow(dtOriginalData.Rows[iCopyIndex]); 
}
dtOriginalData = dtNew; 

Profiter de la, Andrew M

1
répondu Andrew Marais 2012-03-23 09:08:50

j'ai résolu mon erreur datatable-internal-index de cette façon:

a changé CellEndEdit en CellBeginEdit événement. Également... éviter d'utiliser inutilement NULLs:

Private Sub User_role_groupDataGridView_CellBeginEdit(sender As Object, e As DataGridViewCellCancelEventArgs) Handles User_role_groupDataGridView.CellBeginEdit
    Try 
        If Not Me.User_role_groupDataGridView.Rows(e.RowIndex).IsNewRow Then Me.User_role_groupDataGridView.Rows(e.RowIndex).Cells("last_modified_user_group_role").Value = Now
    Catch ex As Exception
        Me.displayUserMessage(ex.ToString, Me.Text, True)
    End Try
End Sub
1
répondu Samuel Darteh 2015-12-02 17:37:05

j'ai eu le même problème (table index corrompu avec 5) sur l'ajout de lignes programaticly à un ensemble de données qui est lié à la datagridview. Je n'ai pas tenu compte du fait qu'il y avait un eventhandler sur L'événement AddRow de datagridview, qui fait une certaine initialisation au cas où l'utilisateur lancerait la nouvelle ligne par L'interface utilisateur. Dans exceptions stack trace rien n'a été vu de lui. En désactivant l'événement, je pourrais résoudre ça rapidement. Je n'y suis arrivé qu'en lisant quelques commentaires ici en profondeur. 2h pas trop pour des questions comme ça :-), je pense. Vous pouvez le trouver en définissant le point de rupture dans chaque eventhandler assigné à datgridview qui est lié à l'ensemble de données.

1
répondu rgaab 2016-02-21 00:37:06

ne pouvez-vous pas simplement utiliser:

dtData.Columns.Add("TestColumn", typeof(Decimal), "Price * Quantity");
0
répondu balexandre 2009-01-16 20:50:49

il m'est arrivé la même chose. Winforms, .NET 3.5, inopinément obtenu cette erreur en essayant de définir une des colonnes dans la rangée dactylographiée. Le Code était plutôt vieux et fonctionnait depuis longtemps donc c'était une sorte de surprise désagréable...

j'avais besoin de mettre de nouveaux Sortno's dans la table dactylographiée TadaTable dans l'ensemble de données TadaSet.

Ce qui m'a aidé, vous pouvez aussi essayer ceci:

int i = 0;
foreach (TadaSet.TadaTableRow row in source)
{
     row.BeginEdit(); //kinda magical operation but it helped :)
     // Also you can make EndEdit() for each row later if you need...
     short newNo = i++;
     if (newNo != row.SortNo) row.SortNo = newNo; //here was the crash
}
0
répondu Schnapz 2011-11-22 12:14:45

dans mon cas, la version Framework est 2.0. La source d'un problème était dans DataView ListChanged event. Le code ci-dessous initialise la nouvelle ligne avec quelques valeurs par défaut.

private void dataView_ListChanged(object sender, ListChangedEventArgs e)
{
    if (e.ListChangedType == ListChangedType.ItemAdded)
    {
        DataView v = (DataView)sender;
        DataRowView drv = v[e.NewIndex];

        // This "if" works fine
        if (drv["Foo"] == DBNull.Value)
        {
            drv["Foo"] = GetFooDefault();
        }

        // This "if" brakes the internal index     
        if (drv["Bar"] == DBNull.Value && drv["Buz"] != DBNull.Value)
        {
            drv["Bar"] = drv["Buz"];
        }
    }
}

après une certaine enquête, il est devenu clair que L'événement ItemAdded est appelé au moins deux fois par rangée. La première fois que L'UI crée une nouvelle ligne pour entrer des données et la seconde fois, je ne suis pas sûr, mais ressemble à quand DataRowView est ajouté à un DataView.

Le premier " si " ne fonctionne que lorsque L'ItemAdded est appelé première fois. Sur le second appel, la colonne "Foo" est déjà peuplée et laissée telle quelle.

cependant le code de défaut de la colonne "barre" peut être exécuté sur les deux appels. En fait, dans mon cas, il a été exécuté seulement sur le deuxième événement ItemAdded, lorsque l'Utilisateur a eu la chance de remplir les données pour la colonne "Buz" (initialement "Buz" a une valeur DBNull).

donc voici des recommandations basées sur mes conclusions:

  • les données de L'événement ListChanged ne peuvent être modifiées que lorsque e.ListChangedType == ListChangedType.ItemAdded .
  • avant de définir la valeur de la colonne, le contrôle doit être effectué pour s'assurer qu'il s'agit du premier événement ajouté (par exemple, si la valeur ne peut pas être nulle lors du second appel, vérifier si elle est DBNull.Value , etc.)
0
répondu Artemix 2012-05-30 08:33:05

voici ce qui semble avoir fonctionné pour ma collègue Karen et moi.nous obtenions cette erreur dans un DataGridView, mais seulement lors de la saisie de données dans une colonne particulière.

Il s'avère que j'avais changé l'ordre des colonnes dans la grille, ne sachant pas qu'il y a du code dans le DataGridView.Sub CellValidated qui annule la valeur dans cette colonne particulière causant le problème.

ce code renvoie à un numéro de colonne spécifique. Si lorsque la colonne 3 de DataGridView originale a été déplacée et est devenue la colonne 1, mais la DataGridView.Code cellvalidé toujours en référence à la colonne 3, l'erreur s'est produite. Changer notre code pour qu'il se réfère à la bonne E. ColumnIndex semble avoir corrigé notre problème.

(il n'était pas facile de changer ce numéro dans notre code. J'espère que ce correctif est titulaire.)

0
répondu Mike Banach 2013-05-01 20:15:44

peut être que vous utilisez les mêmes données dans plusieurs processus en même temps.. Je viens de résoudre ces problèmes en utilisant SYNCLOCK ...

essayez ceci..

SyncLock your datatable

'''' ----your datatable process

End SyncLock
0
répondu URVISH SUTHAR 2014-03-07 17:07:49

j'ai eu le même problème en utilisant des Threads. Ce que j'ai fait était de créer un délégué qui est appelé quand j'ai besoin de fusionner la table.

internal delegate void MergeData (DataTable dataTable1, DataTable dataTable2);

internal static void MergeDataTable (DataTable dataTable1, DataTable dataTable2)
{
    dataTable1.Merge (dataTable2, true);
}

puis pendant l'exécution j'appelle le délégué et l'erreur ne se produit pas.

Delegates.MergeData mergeData = new Delegates.MergeData (Delegates.MergeDataTable);

object [] paramsMerge = {dataTable1, dataTable2};

this.Invoke (mergeData, paramsMerge);
0
répondu Ailton 2017-12-29 13:25:04

j'ai rencontré le même problème et c'est ce qui l'a corrigé pour moi: débordement de pile - index interne est corrompu .

si vous utilisez des threads avec un ensemble de données, cette erreur se produira.

dans mon cas, j'essayais de créer une nouvelle ligne pour un ensemble de données dans une méthode qui fonctionnait en threads.

une façon était d'utiliser SyncLock autour de la méthode qui crée la ligne ou une autre façon (et probablement encore mieux) était de créer les lignes en dehors des threads.

en gros, mon code ressemble à quelque chose comme ça:

    Dim elements As New List(Of element)
    Dim dataRows As New List(Of MyDataSet.Row)

    For i As Integer = 0 To elements.Count - 1
        dataRows.Add(Me.Ds.Elements.NewElementsRow)
    Next

    Parallel.For(0, elements.Count, Sub(i As Integer)
                                        Me.CreateElementRow(elements(i), dataRows(i))
                                    End Sub)

dans la méthode CreateElementRow je fais beaucoup de calculs dans les threads.

Espérons que cette aide.

-1
répondu mrc 2017-05-23 12:02:27