IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Accès aux données Discussion :

DataSet : dataTable.Fill dans un BackgroundWorker déclenche une exception


Sujet :

Accès aux données

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2009
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 163
    Points : 120
    Points
    120
    Par défaut DataSet : dataTable.Fill dans un BackgroundWorker déclenche une exception
    Bonjour à tous,

    Dans une petite application j’utilise une Base de données SQL Server 2000 chargée en mémoire dans un DataSet. Après le démarrage, pour gagner du temps, je récupère les données d’une table grâce à un tableAdapter.Fill(dataset.MaTable) dans un BackgroundWorker : c'est-à-dire dans un autre thread.

    Le problème est que j’ai une exception déclenché à ce niveau là. Cela ne survient que si la sélection (faite par le Fill) contient beaucoup d’enregistrement (plus de 1000).

    Voici l’exception :

    La collection a été modifiée ; l'opération d'énumération risque de ne pas s'exécuter.
    (Collection was modified; enumeration operation might not execute.)
    Je ne comprends pas pourquoi cela plante ici, par plusieurs reprises j’ai utilisé cette méthode sans plantage !
    J’ai lu en cherchant sur google que l’une des causes probable de cette erreur est que la « collection » (ma datatable) serait modifiée par un autre thread (le thread principal ?)

    Mais bien qu’ayant mis des points d’arrêt partout, je ne vois pas ce qui pourrait modifier ma datatable ! Comment faire pour « espioner » la modification de la collection par un autre thread ?

    Si quelqu'un à une idée sur le problème, je l'en remercie !

  2. #2
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Si la DataTable est bindée à des Controls (ComboBox, DataGridView, ...), il faudrait peut-être supprimer le(s) binding(s) le temps d'exécuter le BackGroundWorker et le(s) restaurer une fois que le BackGroundWorker a achevé son travail.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Essaie de faire un BeginLoadData sur la table avant le Fill, et EndLoadData après (ou BeginInit/EndInit, je sais plus trop...). Ca devrait empêcher que les contrôles bindés à cette table (DataGridView par exemple) ne se mettent à jour avant la fin du Fill

  4. #4
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Ou aussi SuspendLayout(), puis ResumeLayout() sur la Form ?
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Février 2009
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 163
    Points : 120
    Points
    120
    Par défaut
    Je teste ça demain matin ^^

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Février 2009
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 163
    Points : 120
    Points
    120
    Par défaut
    J'ai testé à la foi SuspendLayout, BeginInit et BeginLoadData : rien n'y fait....

    Voici le detail de l'exeption :
    à System.Data.RBTree`1.RBTreeEnumerator.MoveNext()
    à System.Data.Index.InitRecords(IFilter filter)
    à System.Data.Index..ctor(DataTable table, Int32[] ndexDesc, IndexField[] indexFields, Comparison`1 comparison, DataViewRowState recordStates, IFilter rowFilter)
    à System.Data.DataTable.GetIndex(IndexField[] indexDesc, DataViewRowState recordStates, IFilter rowFilter)
    à System.Data.DataView.UpdateIndex(Boolean force, Boolean fireEvent)
    à System.Data.DataView.SetIndex2(String newSort, DataViewRowState newRowStates, IFilter newRowFilter, Boolean fireEvent)
    à System.Data.RelatedView.SetIndex(String newSort, DataViewRowState newRowStates, IFilter newRowFilter)
    à System.Data.DataRowView.CreateChildView(DataRelation relation)
    à System.Data.DataRelationPropertyDescriptor.GetValue(Object component)
    à DevExpress.Data.Helpers.ListDataControllerHelper.DevExpress.Data.IRelationList.GetDetailList(Int32 listSourceRow, Int32 relationIndex)
    à DevExpress.Data.Helpers.ListDataControllerHelper.DevExpress.Data.IRelationList.IsMasterRowEmpty(Int32 listSourceRow, Int32 relationIndex)
    à DevExpress.Data.DataController.IsDetailRowEmpty(Int32 controllerRow, Int32 relationIndex)
    à DevExpress.Data.DataController.IsDetailRowEmptyCached(Int32 controllerRow, Int32 relationIndex)
    à DevExpress.XtraGrid.Views.Grid.GridView.IsMasterRowEmptyCached(Int32 rowHandle)
    à DevExpress.XtraGrid.Views.Grid.ViewInfo.GridViewInfo.CreateRowInfo(GridRow row)
    à DevExpress.XtraGrid.Views.Grid.ViewInfo.GridViewInfo.CalcRowsDrawInfo()
    à DevExpress.XtraGrid.Views.Grid.ViewInfo.GridViewInfo.CalcGridInfo()
    à DevExpress.XtraGrid.Views.Grid.ViewInfo.GridViewInfo.Calc(Graphics g, Rectangle bounds)
    à DevExpress.XtraGrid.Views.Grid.ViewInfo.GridViewInfo.FullRecalcScroll(Graphics g, Rectangle bounds)
    à DevExpress.XtraGrid.Views.Grid.ViewInfo.GridViewInfo.CalcAfterVertScrollCore(Graphics g, Rectangle bounds, Boolean useCache)
    à DevExpress.XtraGrid.Views.Grid.ViewInfo.GridViewInfo.CalcAfterVertScroll(Graphics g, Rectangle bounds, Boolean useCache)
    à DevExpress.XtraGrid.Views.Grid.GridView.RefreshRows(Boolean useCache, Boolean afterScroll)
    à DevExpress.XtraGrid.Views.Grid.GridView.CalculateDataCore()
    à DevExpress.XtraGrid.Views.Grid.GridView.CalculateData()
    à DevExpress.XtraGrid.Views.Base.BaseView.CheckViewInfo()
    à DevExpress.XtraGrid.Views.Base.BaseView.Draw(GraphicsCache e)
    à DevExpress.XtraGrid.GridControl.OnPaint(PaintEventArgs e)
    à System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs)
    à System.Windows.Forms.Control.WmPaint(Message& m)
    à System.Windows.Forms.Control.WndProc(Message& m)
    à DevExpress.XtraEditors.Container.EditorContainer.WndProc(Message& m)
    à DevExpress.XtraGrid.GridControl.WndProc(Message& m)
    à System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    à System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    à System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    à System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    à System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
    à System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    à System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    à System.Windows.Forms.Application.Run(Form mainForm)
    à CDL_Quotas.Program.Main() dans C:\Documents and Settings\nicolas\Mes documents\Visual Studio 2008\Projects\CDL_Quotas\trunk\CDL_Quotas\CDL_Quotas\Program.cs:ligne 23
    à System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
    à System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
    à Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    à System.Threading.ThreadHelper.ThreadStart_Context(Object state)
    à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    à System.Threading.ThreadHelper.ThreadStart()

    Elle survient dans la classe Program.cs :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
       static class Program
        {
            /// <summary>
            /// Point d'entrée principal de l'application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                // For use OfficeSkin
                DevExpress.UserSkins.OfficeSkins.Register();
                DevExpress.Data.CurrencyDataController.DisableThreadingProblemsDetection = true;
                //DevExpress.UserSkins.BonusSkins.Register();
     
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
    //======================================================
                Application.Run(new ViewCommande()); <============ ICI
    //======================================================
            }
        }

    EDIT :
    ======

    L'erreur est peu être du à DevExpress (très bonne boite de composant pour les Grid et PivotGrid, etc). Lors de l'utilisation de BackgroudWorker, j'ai été obligé de mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DevExpress.Data.CurrencyDataController.DisableThreadingProblemsDetection = true;
    pour désactiver les "alerte" exception. Mais après avoir supprmé cette ligne, l'erreur survient au même endroit : sur le Fill dans mon BackgroundWorker !

    Le détail de l'erreur est le suivant :

    Cross thread operation detected. To suppress this exception, set DevExpress.Data.CurrencyDataController.DisableThreadingProblemsDetection = true


    à DevExpress.Data.CurrencyDataController.ThrowCrossThreadException()
    à System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
    à System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
    à System.Threading.ExecutionContext.runTryCode(Object userData)
    à System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
    à System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
    à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    à System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
    à System.Windows.Forms.Control.InvokeMarshaledCallbacks()
    à System.Windows.Forms.Control.WndProc(Message& m)
    à DevExpress.XtraEditors.Container.EditorContainer.WndProc(Message& m)
    à DevExpress.XtraGrid.GridControl.WndProc(Message& m)
    à System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    à System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    à System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    à System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    à System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
    à System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    à System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    à System.Windows.Forms.Application.Run(Form mainForm)
    à CDL_Quotas.Program.Main() dans C:\Documents and Settings\nicolas\Mes documents\Visual Studio 2008\Projects\CDL_Quotas\trunk\CDL_Quotas\CDL_Quotas\Program.cs:ligne 23
    à System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
    à System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
    à Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    à System.Threading.ThreadHelper.ThreadStart_Context(Object state)
    à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    à System.Threading.ThreadHelper.ThreadStart()

Discussions similaires

  1. [MySQL-5.6] Trigger qui déclenche une exception
    Par loustalet dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 18/04/2014, 21h13
  2. [XE2]TIdHTTP.Post qui déclenche une exception EConvertError
    Par hohorga dans le forum Composants VCL
    Réponses: 4
    Dernier message: 08/10/2012, 12h15
  3. afficher Dlg fille dans une Dlg mère
    Par kurt_nova dans le forum MFC
    Réponses: 5
    Dernier message: 27/06/2007, 08h33
  4. Comment ajouter une feuille MDI fille dans une DLL ?
    Par Najdar dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 13/02/2007, 16h30
  5. Réponses: 11
    Dernier message: 06/12/2005, 08h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo