Comment créer plusieurs instances d'une même classe. [Résolu]

ianis24 87 Messages postés dimanche 20 août 2006Date d'inscription 13 janvier 2011 Dernière intervention - 10 janv. 2011 à 22:20 - Dernière réponse : ianis24 87 Messages postés dimanche 20 août 2006Date d'inscription 13 janvier 2011 Dernière intervention
- 13 janv. 2011 à 11:30
Bonjour,
Je rencontre un problème.

Mon application lance plusieurs threads qui doivent utiliser une classe.
(Classe utilisant un TCPclient et utilisant ~5 secondes a répondre )

Je recontre cette érreur :

A first chance exception of type 'System.ObjectDisposedException' occurred in System.dll


D'après quelques recherches il semblerait qu'une seul instance de la classe est utilisée par toutes les threads.
lors de l'utilisation d'une unique thread l'application fonctionne.

Merci.
Afficher la suite 

Votre réponse

9 réponses

Meilleure réponse
ianis24 87 Messages postés dimanche 20 août 2006Date d'inscription 13 janvier 2011 Dernière intervention - 13 janv. 2011 à 11:30
3
Merci
Problème résolue via les Delegates.

Merci ianis24 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 93 internautes ce mois-ci

Commenter la réponse de ianis24
NHenry 14278 Messages postés vendredi 14 mars 2003Date d'inscription 21 octobre 2018 Dernière intervention - 10 janv. 2011 à 22:41
0
Merci
Bonjour,

Non, c'est que tu fais un .Close ou .Dispose de ton objet, de fait, après tu ne peux plus l'utiliser.

Et dans la pratique, il est possible d'utiliser plus d'une connexion TCP par programme.

Mon site
Commenter la réponse de NHenry
Mayzz 2859 Messages postés mardi 15 avril 2003Date d'inscription 26 novembre 2013 Dernière intervention - 10 janv. 2011 à 23:33
0
Merci

Mon application lance plusieurs threads qui doivent utiliser une classe.
(Classe utilisant un TCPclient et utilisant ~5 secondes a répondre )


Oui à partir du moment ou tu instancie tes classes dans des thread différents, elle ne peuvent pas être de la même instance (sauf si tu passe cette instance en argument).

Par ailleurs, si on s'en rend bien compte lors ce que l'on utilise une classe FTPWebRequest par exemple, celle-ci utilise une classe Socket, lors ce que tu fais plusieurs requête depuis le même thread la connexion est conservé, mais si tu instancie des FTPWebRequest dans des threads différents les connexion seront créés à chaque fois (une par thread).

Donc partage donc l'avis de NHenry.

Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
Commenter la réponse de Mayzz
ianis24 87 Messages postés dimanche 20 août 2006Date d'inscription 13 janvier 2011 Dernière intervention - 11 janv. 2011 à 01:17
0
Merci
Je souhaite justement utiliser plusieurs connexion.
Et la est le problème, celles-ci ne s'effectue pas lorsque plusieurs thread sont lancés en même temps.

D'où le message :


A first chance exception of type 'System.ObjectDisposedException' occurred in System.dll


(Je souhaite réaliser plusieurs connexion FTP)
Commenter la réponse de ianis24
Mayzz 2859 Messages postés mardi 15 avril 2003Date d'inscription 26 novembre 2013 Dernière intervention - 11 janv. 2011 à 09:21
0
Merci
C'est en fait ce que l'on te dis, le problème ne vient pas du fait que ton application soit multi-threads mais plutôt du fait que tu as une erreur dans ton code

D'après quelques recherches il semblerait qu'une seul instance de la classe est utilisée par toutes les threads.


Pour moi ceci est faut, d'ailleurs si t'as le lien d'ou tu tire cette information je veux bien y jeter un œil.

A first chance exception of type 'System.ObjectDisposedException' occurred in System.dll

Aussi, ce qu'il faut savoir c'est qu'en générale, les exceptions de première chance ne gène pas le fonctionnement du programme, l'EDI l'affiche dans la fenêtre de sortie un simple message mais le programme continu à fonctionner normalement.

Je t'invite donc à revoir ton code, voir même à nous en poster une partie ici.

(Classe utilisant un TCPclient et utilisant ~5 secondes a répondre )


Je n'avais pas prêté attention à cette phrase plus que ça mais si tu entends par là que le temps de connexion est de 5 secondes alors il y a forcément un problème. Tu test bien entendu sur un serveur local (genre FileZila) sur lequel tu as autorisé les connexion illimités par IP, car si ce n'est pas le cas ne cherches pas plus loin. Il y a aussi le problème du timeout, si tu ne fais que te connecter au serveur sans effectuer d'authentification alors au bout d'un certain temps celui-ci te rejète c'est normal.

Aussi, si tu souhaites réaliser des connexion FTP alors utilises le FTPWebRequest et non les Socket ou le TCPClient, ainsi tu auras l'avantage de ne pas avoir à saisir le protocole FTP à la main.
Par contre cela à ses inconvénients, le FTPWebRequest ne gère que les connexion FTP et FTPES, il ne gère pas les connexion implicites (FTPS) ni le SSH (SFTP). Aussi il n'est pas possible d'émettre des commandes personnalisés vers le serveur (Quoi que, à voir si ils ont modifié avec le FW4 sous 2010...).

Voila.

Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
Commenter la réponse de Mayzz
ianis24 87 Messages postés dimanche 20 août 2006Date d'inscription 13 janvier 2011 Dernière intervention - 11 janv. 2011 à 11:14
0
Merci
Merci pour ta réponse en modifiant un peut le code j'obtiens l'erreur suivante.
A first chance exception of type 'System.Net.Sockets.SocketException' occurred in System.dll

Cette erreur semble provenir de la void connect()de ma classe.



Voici ma Classe :
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace FTPlibcheck
{
    public class ClassFTP
    {
        private static TcpClient tcpclient;
        private static string Data =  null;
        private static NetworkStream nstream = null;
        private static Queue<string> pck_queue;
        private static System.Threading.Thread rcv_th = null;
        public string strHost, strUser, strPass = "";
        public string strSystem = "";
        public bool servWork = false;
        

        public ClassFTP()
        {
            tcpclient = new TcpClient();
            pck_queue = new Queue<string>();
        }

        public void connect()
        {
            try
            {
                tcpclient.Connect(strHost, 21);
                if (!tcpclient.Connected)
                {
                    //Environment.Exit(0);
                    return;
                }
                nstream = tcpclient.GetStream();
                rcv_th = new System.Threading.Thread(new System.Threading.ThreadStart(rcv));
                rcv_th.Start();

            }
            catch (Exception)
            {
                nstream.Close();
                pck_queue.Clear();
                tcpclient.Close();
               //connect();
            }
        }

        void rcv()
        {
            while (tcpclient.Connected)
            {
                Byte[] databyt = new Byte[tcpclient.Available];
                try
                {
                    nstream.Read(databyt, 0, databyt.Length);
                }
                catch
                {
                }
                string str00 = Encoding.ASCII.GetString(databyt);
                string[] str01 = null;
                str01 = str00.Split(new char[] { '\n' });
                foreach (string str02 in str01)
                {
                    pck_queue.Enqueue(str02);

                    ReceiveData();
                }
            }
        }

        static void send(string Data)
        {

            Data += "\r\n";

            byte[] DataToSend = Encoding.UTF8.GetBytes(Data);
            nstream.Write(DataToSend, 0, DataToSend.Length);

        }

        void ReceiveData()
        {
            if (pck_queue.Count != 0)
            {
                for (int i = 0; i < pck_queue.Count; i++)
                {
                    Data = pck_queue.Dequeue();
                    if (Data != "")
                    {
                        string aData "", bData "";
                        bData = Data.Substring(0, 3);
                        Console.WriteLine("rcv : " + Data);
                        switch (bData)
                        {
                            case "220": Thread.Sleep(10);
                                send("USER " + strUser);
                                break;
                            case "331": Thread.Sleep(100);
                                send("PASS " + strPass);
                                break;
                            case "230": Thread.Sleep(100);
                                servWork = true;
                                send("SYST");
                                break;
                            case "530": Thread.Sleep(100);
                                servWork = false;
                                break;
                            case "215": Thread.Sleep(100);
                                aData = Data.Substring(4, Data.Length - 5);
                                strSystem = aData;
                                send("QUIT");
                                break;
                        }
                    }
                }
            }
        }
    }
}


Et la fonction appelée simultanément par les Threads :
    Private Sub FTPcheck(ByVal cIndex As Integer, ByVal strHost As String, ByVal strUser As String, ByVal strPass As String)

        Dim cFTP As ClassFTP  = New ClassFTP
        cFTP.strHost = strHost
        cFTP.strUser = strUser
        cFTP.strPass = strPass
        Try
            cFTP.connect()
            fwait(3000) ' millisec
            Debug.Print(cFTP.strSystem)
        Catch
        End Try 
    End Sub


Je pense que le problème a lieu dans le code ci-dessus.
Je préfère utiliser les sockets pour un protocole personnalisé.
Commenter la réponse de ianis24
NHenry 14278 Messages postés vendredi 14 mars 2003Date d'inscription 21 octobre 2018 Dernière intervention - 12 janv. 2011 à 13:58
0
Merci
Bonjour,

Déjà c'est un code C# et pas VB, sa place aurai été donc chez www.csharpfr.com, mais passons.

Tu test :
tcpclient.Connected
Dans tes threads, vérifie aussi si :
tcpclient!=null
et (je n'ai pas regardé la doc, à voir si présent)
tcpclient.Disposed

Ensuite, je ne comprend pas exactement pourquoi la connexion se ferme, peut être un timeout coté serveur ?

Sinon, dans tes threads, pense à mettre :
System.Threadding.Thread.Sleep(10) '10 millisecondes)
pour laisser un peu souffler la machine.

Mon site
Commenter la réponse de NHenry
Mayzz 2859 Messages postés mardi 15 avril 2003Date d'inscription 26 novembre 2013 Dernière intervention - 12 janv. 2011 à 14:22
0
Merci
Aussi >

foreach (string str02 in str01)
                {
                    pck_queue.Enqueue(str02);

                    ReceiveData();
                }


Tu utilises une file d'attente mais tu ne laisse pas s'empiler les éléments, tu appelles de suite la méthode ReceiveData, ce n'est pas très logique, soit tu utilises un string simple ou soit une liste mais tu appelles ReceiveData en fin de boucle :

foreach (string str02 in str01)
                {
                    pck_queue.Enqueue(str02);

                }   
         ReceiveData();


Bien entendu ton erreur ne provient pas de là, c'est juste une question d'optimisation ou plutôt de proporeté/logique du code...

Au niveau du serveur FTP quel est-il ? As-tu autorisé la connexion multiple par adresse IP ? Te connectes-tu avec le même login/pass ? Si oui, as-tu autorisé les connexion multiples par login ?

Si déjà tu est sûr de tout cela, on aura fait un grand pas !

++

Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
Commenter la réponse de Mayzz
ianis24 87 Messages postés dimanche 20 août 2006Date d'inscription 13 janvier 2011 Dernière intervention - 12 janv. 2011 à 18:11
0
Merci
J'ai un peut avancé, J'ai supprimer les static de ma classe.
Je n'ai plus d'erreurs au niveau des sockets, les connexion FTP ce font correctement et simultanément.
Par contre, j'ai remarquer que cFTP.strSystem est partager par toutes les threads.
En gros des threads avec des connexion FTP factices ( ne fonctionnant pas ) semble retourner la valeur d'autres threads.
Commenter la réponse de ianis24

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.