Woslike
Messages postés46Date d'inscriptionmercredi 25 juillet 2012StatutMembreDernière intervention12 septembre 2013
-
31 oct. 2012 à 13:04
madkeyboard
Messages postés100Date d'inscriptionmercredi 27 avril 2011StatutMembreDernière intervention21 décembre 2012
-
13 nov. 2012 à 11:13
Bonjours tout le monde,
Je viens à vous pour obtenir de l'aide !
Je vous explique ma situation :
J'ai développé un petit programme ( sur appareil mobile ) qui permet d'envoyer ou de récupérer des fichiers sur un FTP.
=> Le programme fonctionne à merveille , seulement lorsque la connexion est longue ou que le fichier est gros l'appareil ce fige et je perd tout contrôle durant l'exécution du transfert ou de la connexion.
J'ai donc décider d'exécuter les manips en arrière plan ! Pour cela j'utilise des Threads !
Mais... je n'y arrive pas !
Donc voila ma question est : Comment exécuter cette tâche en arrière plan ( lorsqu'on appuit sur Envoi ou Recup ) tout en gardant le contrôle sur le programme.
Je vous remercie d'avance pour vos réponse !
Voici l'apparence du programme ainsi que son code :
CODE C# :
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net;
using System.IO;
namespace SmartDeviceProject4
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void menuItem1_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void btnFTPSave_Click(object sender, EventArgs e)
{
this.demoThreadEnvoi = new Thread(ThreadProcSafeEnvoi);
this.demoThreadEnvoi.Start();
}
private Thread demoThreadEnvoi = null;
private void btnFTPRecup_Click(object sender, EventArgs e)
{
this.demoThreadRecup = new Thread(ThreadProcSafeRecup);
this.demoThreadRecup.Start();
}
private Thread demoThreadRecup = null;
bool IsConnect = false;
delegate void ThreadEnvoi();
delegate void ThreadRecup();
delegate void SetTextCallback(string txt);
public void ThreadProcSafeEnvoi()
{
if (this.InvokeRequired)
{
ThreadEnvoi d = new ThreadEnvoi(this.ThreadProcSafeEnvoi);
this.Invoke(d);
}
else
{
ftp FTP = new ftp();
infox.Items.Clear();
if (File.Exists("\" + txtlocal.Text.Trim()))
{
MessageXX("Fichier trouvé");
if (IsConnect = FTP.InitializeFTP())
{
MessageXX("FTP Initialisé");
if (IsConnect = FTP.ConnectToFTPServer(txtServerIP.Text.Trim(), txtUsername.Text.Trim(), txtPassword.Text.Trim()))
{
MessageXX("FTP Connecté");
if (IsConnect = FTP.UploadFile("\" + txtlocal.Text.Trim(), txtdistant.Text.Trim()))
MessageXX("Fichier envoyé");
else
MessageXX("Fichier non-envoyé");
if (IsConnect = !FTP.CloseFTP())
MessageXX("FTP Non-Déconnecté");
else
MessageXX("FTP Déconnecté");
}
else
MessageXX("FTP Non-Connecté");
}
else
MessageXX("FTP Non-Initialisé");
}
else
MessageBox.Show("Fichier introuvable");
}
}
public void ThreadProcSafeRecup()
{
if (this.InvokeRequired)
{
ThreadRecup d = new ThreadRecup(this.ThreadProcSafeRecup);
this.Invoke(d);
}
else
{
ftp FTP = new ftp();
infox.Items.Clear();
if (IsConnect = FTP.InitializeFTP())
{
MessageXX("FTP Initialisé");
if (IsConnect = FTP.ConnectToFTPServer(txtServerIP.Text.Trim(), txtUsername.Text.Trim(), txtPassword.Text.Trim()))
{
MessageXX("FTP Connecté");
if (IsConnect = FTP.DownloadFile(txtdistant.Text.Trim(), "\" + txtlocal.Text.Trim()))
MessageXX("Fichier récupéré");
else
MessageXX("Fichier non-récupéré");
if (IsConnect = !FTP.CloseFTP())
MessageXX("FTP Non-Déconnecté");
else
MessageXX("FTP Déconnecté");
}
else
MessageXX("FTP Non-Connecté");
}
else
MessageXX("FTP Non-Initialisé");
}
}
public void MessageXX(string txt)
{
if (this.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(MessageXX);
this.Invoke(d, new object[] { txt });
}
else
{
this.infox.Items.Add(txt);
}
}
}
}
madkeyboard
Messages postés100Date d'inscriptionmercredi 27 avril 2011StatutMembreDernière intervention21 décembre 20121 6 nov. 2012 à 11:17
Salut !
ça m'a l'air plutôt cohérent tout ça !
Je dis cohérent... Mais en fait je ne vois pas l'intérêt du Invoke ???
Tu ne manipule aucun éléments de ta form ??
Et du coup, je ne vois nul part de définition pour "infox" ! ça manque un peu de commentaire tout ça :s
Bref, pour moi le problème vient de l'Invoke : lorsque la méthode considère qu'il faut un Invoke (InvokeRequired), tu relance la méthode entière, au lieu de seulement la partie concerné par cet invoke (modif d'éléments de la Form) !
Du coup, dès que tu passe dans ton Invoke, c'est la thread de ta form qui se tape toute la com avec le ftp, et ton thread secondaire n'a plus du tout de raison d'être !!
Pour moi, à vérifier si tu as vraiment l'utilité de cet Invoke, et si c'est le cas, cible précisément quelles lignes de codes en ont besoin (cherche les exceptions ^^), passe les dans une autre méthode qui celle-ci sera exécuté par le thread de la form grâce à l'Invoke, tandis que la com ftp continuera a se faire dans le thread demoThreadRecup ou demoThreadEnvoi !
Woslike
Messages postés46Date d'inscriptionmercredi 25 juillet 2012StatutMembreDernière intervention12 septembre 20131 6 nov. 2012 à 16:03
Ah ou exactement, désolé de manquer de précision :
infox => ListBox qu'on voit à l'écran
txt*** => Textbox correspondant au nom ***
Voila ^^
Même en manipulant des Threads, l'envoi des fichiers (ouverture FTP, envoi, fermeture ) bloque le formulaire et je ne peux rien faire. J'avoue que là, je suis un peu perdu :X
Si tu a une idée de comment avoir le contrôle sur le programme pendant l'envoi, tu m'enlèvera l'épine que j'ai au pied !
madkeyboard
Messages postés100Date d'inscriptionmercredi 27 avril 2011StatutMembreDernière intervention21 décembre 20121 8 nov. 2012 à 10:29
Ha, je comprends mieux !!!
Je vais te dire comment je fonctionnais dans ce genre de cas moi :
Je me fais une méthode avec comme arguments 2 ou 3 paramètres, selon le nombres d'éléments à manipuler dans la form.
Un des arguments (un string pour moi) définie ce que tu veux faire (par ex : "Refresh_IHM" ou bien "TexteIn_txt", ou encore "Hide_infox" ou ce que tu veux, on s'en fout !), puis les autres arguments précise de que tu aura besoin (par ex pour un argument 1 = "TexteIn_txt", y'aura un argument 2 "Texte que j'ai besoin d'afficher").
Ensuite cette méthode (à 2 arguments on va dire), je l'appelle grâce à la fonction Invoke !
Vu que tu est dans la même classe, c'est donc assez facile : tu crée un délégué avec le nombre d'arguments que tu as besoin (2 string dans mes expl), et chaque fois que tu veux faire une modif de l'IHM, tu appelle cette méthode avec un coup d'Invoke, du genre :
Invoke(MethodeMaJ_IHM, new object[] {"TexteIn_txt", "trululu"});
Si tu as d'autres préférence de fonctionnement, fais à ta sauce, mais pousse dans cette direction !
Mad Keyboard
Vous n’avez pas trouvé la réponse que vous recherchez ?
madkeyboard
Messages postés100Date d'inscriptionmercredi 27 avril 2011StatutMembreDernière intervention21 décembre 20121 12 nov. 2012 à 11:27
Salut,
Pour ce qui est de la connexion ftp, c'est vraiment pas mon domaine, je pourrais pas t'aider à débugger, mais normalement si ton thread est bien fait, ton formulaire ne devrait pas planter (du moins pas tout de suite ^^)
Est-ce que tu peux poster les modifs que tu as fait sur ton code, qu'on puisse voir ce qui cloche ?
(ps : dsl pour le temps de reponse, j'étais un week-end, sans internet ^^)