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

C# Discussion :

[C#] Cannot access a disposed object


Sujet :

C#

  1. #1
    Membre éclairé
    Inscrit en
    Juin 2007
    Messages
    359
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 359
    Par défaut [C#] Cannot access a disposed object
    Bonjour,
    J'ai une form FEnrouleuse qui s'ouvre très bien, et qui lorsque je la ferme, puis la réouvre, me sort un "Cannot access a disposed object", alors même que je l'ai recréé,...

    Voila mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if(FEnrouleuse == null)
                        FEnrouleuse = new FEnrouleuse(this, 0);
                    FEnrouleuse.Width = (this.Width - (3 * hSpace))*2 / 3;
                    FEnrouleuse.Height = (this.Height - (6 * vSpace));
                    FEnrouleuse.Visible = true;
                    FEnrouleuse.Location = new Point(0, 0);                                FEnrouleuse.Visible = true;
                    FEnrouleuse.Show();
    Et mon bug se produit à chaque fois sur FEnrouleuse.Visible ou FEnrouleuse.Show(); (le premier rencontré)
    Il semblerait que lors de la destruction, je dispose quelque chose qu'il ne reconstruit pas ensuite,...

    Voila donc le OnClosed de ma Form FPlanning, dont hérite FEnrouleuse:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    private void FPlanning_FormClosed(object sender, FormClosedEventArgs e)
            {
                this.Dispose();
                switch (TypeFen())
                {  
                    case 0: FormMain.GetInstance().SetNullFenr();
                        break;
                    case 1: FormMain.GetInstance().SetNullFVis();
                        break;
                    case 2: FormMain.GetInstance().SetNullFWaitenr();
                        break;
                    case 3: FormMain.GetInstance().SetNullFWaitVis();
                        break;
                }
            }
    Et ce que font les SetNull c'est ça:
    Code : 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
    public void SetNullFenr()
            {
                FEnrouleuse = null;
            }
            public void SetNullFWaitVis()
            {
                FWaitVis = null;
            }
            public void SetNullFVis()
            {
                FVisseuse = null;
            }
            public void SetNullFWaitenr()
            {
                FWaitEnr = null;
            }
    Donc, rien de très bizarre, je ne comprends pas d'où est ce que sort cette exception,...
    Je Dispose bien u objet, et ensuite j'en recréé un autre!

    Merci de votre aide

  2. #2
    Rédacteur

    Avatar de Jérôme Lambert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2003
    Messages
    4 451
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 4 451
    Par défaut
    Histoire d'être sûr et de ne pas chercher des heures vers une mauvaise voie : tu as essayé en supprimant tout simplement le if pour tester si ta fenêtre a déjà instanciée ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(FEnrouleuse == null)
    Ainsi, la fenêtre sera réinstanciée à chaque fois et si le problème persiste, on va pouvoir explorer d'autres solutions.

  3. #3
    Rédacteur
    Avatar de Paul Musso
    Profil pro
    Inscrit en
    Août 2008
    Messages
    368
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Août 2008
    Messages : 368
    Par défaut
    Qu'elle est la ligne qui plante exactement ?
    Cela ne vient t-il pas d'un autre objet ?

  4. #4
    Membre éclairé
    Inscrit en
    Juin 2007
    Messages
    359
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 359
    Par défaut
    Heu, le problème, c'est que je ne veux pas réinstancier ma fenêtre, sinon, elle va faire un ReadData, et là, je perds les modifs faites par l'utilisateur et je reprends les data de la bdd,
    Quand à savoir l'objet qui plante, si j'ai bien vu, c'est l'objet "Enrouleuse", un UserControl, mais pourtant, je peux y avoir accès ( je dis que je peux y avoir accès car dans le Watch Debug, ces Enrouleuses de ma FEnrouleuse sont bien là).

    Je n'ai aucune idée de comment faire,...

    La ligne qui plante est : FEnrouleuse.Visible = true;
    Et il me dit que cela provient de mon UserControl Enrouleuse, que FEnrouleuse contient bien,...
    Il semblerait que le Dispose() se soit mal adapté à mes UserControl, peut-être que je devrais faire un override de Dispose pour mes UserControls ?

    PS: Jérôme Lambert, j'ai fait ce que tu avais dit, et le, même problème se reproduit, avec l'instanciation à tous les coups,...

  5. #5
    Membre éclairé
    Inscrit en
    Avril 2006
    Messages
    346
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 346
    Par défaut
    Bonjour,

    dans l'évènement FPlanning_FormClosed tu appelles:

    Donc ta form FEnrouleuse qui hérite de la form FPlanning est diposé dès que tu la fermes.
    Donc il est normal que lors d'une réouverture et de l'appel de la méthode

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FEnrouleuse.Visible = true;
    tu reçoives le message Cannot access a disposed object

    Pour moi, l'appel de la méthode dans l'évènement de fermeture ne sert à rien.

    Dans la fenêtre appelante, je suppose que tu as définies une variable privée de type FEnrouleuse.
    Ainsi dans la méthode surchargée Dipose de la form appelante, tu devrais écrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if (FEnrouleuse != null)
        FEnrouleuse.Dispose();
    ++

  6. #6
    Membre éclairé
    Inscrit en
    Juin 2007
    Messages
    359
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 359
    Par défaut
    Merci zoaax pour ta réponse, mais comment fait on pour faire une "méthode surchargée Dipose" ?

    J'ai enlevé le Dispose comme tu m'as dit, mais le problème est toujours là,...

  7. #7
    Membre éclairé
    Inscrit en
    Avril 2006
    Messages
    346
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 346
    Par défaut
    Bonjour,

    comment la form est fermée ?
    Si tu veux pouvoir la réouvrir ensuite, il faut appeler la méthode:

    et non:

    Car avec cette dernière méthode, la form est disposé. Pour plus d'informations, Form.Close, méthode
    Pour parapher la MSDN,
    Pour empêcher la fermeture d'un formulaire au moment de l'exécution, pourvoyez à la gestion de l'événement Closing et affectez la propriété Cancel du CancelEventArgs passé comme paramètre à votre gestionnaire d'événements.
    Et autre point important:

    Lors de l'appel à la méthode Close sur un Form affiché comme une fenêtre non modale, vous ne pouvez pas appeler la méthode Show pour rendre le formulaire visible, car les ressources de ce dernier ont déjà été libérées. Pour masquer un formulaire puis le rendre visible, utilisez la méthode Control.Hide.
    En espérant que cela t'aide.
    Pour faire une méthode surchargée Dispose, tu dois ajouter:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    protected override void Dispose(bool disposing)
    {
    }
    Mais normalement dans une form générée avec le designer, cette méthode est déjà crée.

    ++

  8. #8
    Membre éclairé
    Inscrit en
    Juin 2007
    Messages
    359
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 359
    Par défaut
    Ok, merci zoaax, mais, je veux bien faire un Close, qui me détruise ce FEnrouleuse, pour pouvoir ensuite le reconstruire,...

    Merci pour la méthode surchargé Dispose, j'avais vu après dans le designer, elle a bien été créé.

    Mais, ce que je ne comprends pas c'est que, effectivement, mon j'ai bien disposé ma Form FEnrouleuse, mais je veux ensuite en recréer une autre, et pour ce faire, je fais: FEnrouleuse=new FEnrouleuse(this,0);
    Et après un FEnrouleuse.Visible; je tombe sur cette exception qui me dit que je touche à un object Disposed, j'y comprends rien, il est plus Disposed, je viens de le recréer

  9. #9
    Membre éclairé
    Inscrit en
    Juin 2007
    Messages
    359
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 359
    Par défaut
    J'ai peut-être une piste, dans ma FEnrouleuse, à la création, je fais un TabMachine=Variables.getTabMAchine();
    Or, mon getTabMachine() est en fait ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    static public Enrouleuse[] TABEnrouleuse
            {
                get
                {
                    if (TabE == null)
                    {
                        TabE = (Enrouleuse[])getTabMachine(0);
                    } return TabE; 
                }
            }
    Donc, en gros, je récupère un membre static d'une autre classe,qui a donc dû être Disposé, et c'est lui qui me pose problème

    Enfin, bon, je suis pas sûr, et je voudrais avoir confirmation, et, si possible, comment faire avec le debugger pour visualiser le flag Disposable d'un objet.
    Merci

  10. #10
    Membre éclairé
    Inscrit en
    Juin 2007
    Messages
    359
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 359
    Par défaut
    YESSSSSSSSSSSS
    Ok, c'est résolu, c'est dingue ce que ça fait du bien de résoudre ces bugs !!!

    Merci beaucoup zoaax,Paul Musso et Jérome Lambert, vos réponses m'ont permis de me diriger vers la bonne solution.
    Mon problème étant en fait dû au fait que ma FEnrouleuse faisait appel à un Tableau Statique passé en paramètre, qu'il disposait donc lors de la destruction de ma form, et qui n'était lui pas réinstancié lors de la réinstanciation,...

    Bonne journée

  11. #11
    Membre averti
    Profil pro
    developpeur
    Inscrit en
    Novembre 2003
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : developpeur

    Informations forums :
    Inscription : Novembre 2003
    Messages : 33
    Par défaut
    Bonjour,

    Je remonte ce thread car je suis dans le même cas de figure que Hutin et j'arrive à la même conclusion : le problème survient au moment où la form utilise un tableau statique (que j'appelle "partagé" car je suis en vb mais c'est la même chose).

    Par contre je n'ai pas la solution car je ne comprends pas la phrase de Hutin :

    Tableau Statique passé en paramètre, qu'il disposait donc lors de la destruction de ma form, et qui n'était lui pas réinstancié lors de la réinstanciation
    1) un tableau statique n'est pas détruit lors du dispose d'un objet qui l'utilise, ce qui est normal car il est partagé entre plusieurs instances
    2) un tableau statique ne peut jamais être instancié

    Dans mon cas, ce tableau se trouve dans un module (je suis en vb) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Public TBar(4) As ToolStrip
    Après avoir fait un dispose de la Form, je la réinstantie et j'ai toujours accès au tableau TBar que j'initialise en dynamique et le problème survient quand j'attache un élément de ce tableau (Toolstrip) à la form :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pForm.Controls.Add(TBar(0))
    J'obtiens alors :
    "Cannot access a disposed object"
    ce qui est faux car l'objet existe.

    Je pense que le souci vient du GAC.

    Merci par avance si vous avez une solution.

  12. #12
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 488
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 488
    Par défaut
    Je pense que, logiquement, une Form appel la méthode Dispose de tous les contrôles qu'elle "possède" dans sa liste "Controls".
    En l'ajoutant à la liste de ses contrôles, vous avez, implicitement, associé la durée de vie du contrôle à celle de la Form le contenant.

    Ce n’est vraiment pas naturel de faire des objets de type "contrôle" en static.

    Static ou pas, un objet "Disposed" n'est plus utilisable.

    Soit vous n'en faite pas un static (logique pour moi), soit vous l'enlevez de la liste des Contrôles avant le fin de la Form.

  13. #13
    Membre averti
    Profil pro
    developpeur
    Inscrit en
    Novembre 2003
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : developpeur

    Informations forums :
    Inscription : Novembre 2003
    Messages : 33
    Par défaut
    Merci pour votre réponse et pour LA solution.

    Votre idée de retirer le contrôle partagé (ou static) avant de faire un dispose est la bonne. Il faut faire en plus un clear des items du control.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    frmMenu.Controls.Remove(TBar(0))
          TBar(0).Items.Clear()
          frmMenu.Dispose()
    Encore merci.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. probleme "Cannot access a disposed object"
    Par the-morpher dans le forum Windows Forms
    Réponses: 4
    Dernier message: 04/06/2009, 16h52
  2. pb envoi mail "Could not access 'CDO.Message' object"
    Par adaneels dans le forum ASP.NET
    Réponses: 3
    Dernier message: 07/05/2009, 15h29
  3. Réponses: 15
    Dernier message: 21/01/2007, 22h47
  4. Réponses: 7
    Dernier message: 16/06/2006, 11h09
  5. [SIGBUS] Cannot Access Memory apres un Malloc?
    Par predacktor dans le forum C
    Réponses: 5
    Dernier message: 18/03/2006, 17h11

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