Ca fige ... faut il bosser en asynchrone ?

Résolu
Moomoon07 Messages postés 223 Date d'inscription mercredi 31 mai 2006 Statut Membre Dernière intervention 5 mai 2014 - 8 sept. 2006 à 14:07
Moomoon07 Messages postés 223 Date d'inscription mercredi 31 mai 2006 Statut Membre Dernière intervention 5 mai 2014 - 13 sept. 2006 à 00:52
Salut !

Voici un petit code qui parcours un dossier de MP3 (sous dossiers compris) et qui crée un fichier txt qui liste le nom complet du titre, son répertoire, genre et album (tags).
Selon la taille du dossier, ça devient assez long.
J'ai un problême : le form fige, les labels ne se mettent pas à jour et la barre de chargement ne marche plus lorsque lorsque l'on perd le focus du form et qu'on le reprend.
J'ai lu et + ou - compris le tuto sur threads/synchrone/asynchrone.
Mais est ce que si je modifie mon code de manière à excecuter quelque chose en asynchrone, cela va régler mon problême ? Et dans ce cas, que dois excecuter en asynchrone ? ou peut être des threads ?
(Pour ceux que ça interesserait et qui voudrais la suite du code (getRepertoire, getGenre et getAlbum)... dites le ...)

private
void CreerFichierTXT(
string CheminBibliotheque){

ArrayList Rep =
new
ArrayList();

ArrayList NbTitres =
new
ArrayList();getListeRepertoires(CheminBibliotheque, Rep, NbTitres);

Barre.Minimum = 1;

Barre.Step = 1;

for (int i 0; i < NbTitres.Count; i++)Barre.Maximum Barre.Maximum + System.

Convert.ToInt32(NbTitres[i]);

int NumTitre = 0;

StreamWriter TXT =
new
StreamWriter(CheminBibliotheque +
"/Bibliotheque.txt",
false,
ASCIIEncoding.Default);

for (
int i = 0; i < Rep.Count; i++){

foreach (
string S
in
Directory.GetFiles(Rep[i].ToString(),
"*.mp3", System.IO.
SearchOption.TopDirectoryOnly)){

NumTitre++;

lNbTitres.Text =

"Titre nø" + NumTitre.ToString() +
"/" + Barre.Maximum.ToString();lNomTitre.Text = S;

Barre.PerformStep();

TXT.WriteLine(

"Titre|" + S);TXT.WriteLine(

"Repertoire|" + Rep[i].ToString().Substring(CheminBibliotheque.Length + 1, Rep[i].ToString().Length - (CheminBibliotheque.Length + 1)));TXT.WriteLine(

"Genre|" + getGenre(S));TXT.WriteLine(

"Album|" + getAlbum(S));

this.Refresh();}

}

TXT.Close();}

MERCI D'AVANCE ...

MMN

15 réponses

MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
8 sept. 2006 à 16:26
Voila, sans tester (vu qu'il me manque tes méthodes et que j'ai la flemme :p ), je dirais que ca donne ca :

<hr />

private
delegate
void
ChangeLabelDelegate(
Label label,
string text);

private
delegate
void
IncreaseProgressBarDelegate();

private
delegate
void
SetMaximumDelegate(
int value);

private
ArrayList Rep =
new
ArrayList();

private
ArrayList NbTitres =
new
ArrayList();

private
void ChangeLabel(
Label label,
string text)
{
   label.Text = text;
}

public
void IncreaseProgressBar()
{

   this.Barre.Increment(1);
}

public
void SetMaximum(
int value)
{

   this.Barre.Maximum += value;
}

private
void LaunchProcess(
object data)
{

   string CheminBibliotheque = (
string)data;
   getListeRepertoires(CheminBibliotheque, Rep, NbTitres);

   this.Invoke(
new
SetMaximumDelegate(SetMaximum), NbTitres.Count);

   int NumTitre = 0;

   using (
StreamWriter TXT =
new
StreamWriter(CheminBibliotheque +
"/Bibliotheque.txt",
false,
ASCIIEncoding.Default))
   {

      for (
int i = 0; i < Rep.Count; i++)
      {

         foreach (
string S
in
Directory.GetFiles(Rep[i].ToString(),
"*.mp3", System.IO.
SearchOption.TopDirectoryOnly))
         {
            NumTitre++;

            IAsyncResult iasync1 =
this.BeginInvoke(
new
ChangeLabelDelegate(ChangeLabel),
new
object[] { lNbTitres,
string.Format(
"Titre nø {0} / {1}", NumTitre, Barre.Maximum) });

            IAsyncResult iasync2 =
this.BeginInvoke(
new
ChangeLabelDelegate(ChangeLabel),
new
object[] { lNomTitre, S });

            IAsyncResult iasync3 =
this.BeginInvoke(
new
IncreaseProgressBarDelegate(IncreaseProgressBar));
            TXT.WriteLine(
"Titre|" + S);
            TXT.WriteLine(
"Repertoire|" + Rep[i].ToString().Substring(CheminBibliotheque.Length, Rep[i].ToString().Length - (CheminBibliotheque.Length + 1)));
            TXT.WriteLine(
"Genre|" + getGenre(S));
            TXT.WriteLine(
"Album|" + getAlbum(S));

            this.EndInvoke(iasync1);

            this.EndInvoke(iasync2);

            this.EndInvoke(iasync3);
         }
      }
   }
}
<hr />
que tu appeles ainsi :

<hr />Thread thread =
new
Thread(
new
ParameterizedThreadStart(LaunchProcess));
thread.Start(TonChemin
);
<hr />
Ensuite, a toi d'optimiser ton code, gerer les exceptions, etc.
Je t'ai juste donné de quoi comprendre comment on utilise Threads + delegués synchrones / asynchrones.

J'ai enlevé le code qui définit le minimum et le step de ta barre, il faut que tu le mettes dans le code ou tu initialises tes controles plutot.

Mx
MVP C# 
3
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 36
8 sept. 2006 à 14:13
oui... quand les traitements sont long il FAUT bosser en Asynchrone.

donc, tout ce qui est recherche, téléchargement, traitement...

Sébastien FERRAND (
blog)
Consultant Indépendant
[Microsoft MVP Visual C#]
0
Moomoon07 Messages postés 223 Date d'inscription mercredi 31 mai 2006 Statut Membre Dernière intervention 5 mai 2014
8 sept. 2006 à 14:35
Est ce que tu pourrais préciser un petit peu ta réponse. dans mon code, qu'est ce qu'il faudrait que j'appelle en asynchrone ?

MMN
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
8 sept. 2006 à 14:44
Salut,

Appelle toute ta méthode dans un Thread différent, et change toutes les instuctions qui modifient les propriétés de tes controles (ProgressBar, Labels), afin d'eviter le CrossThreading, avec la meme procédure que celle qu'on t'a donné dans un précédent topic

Mx
MVP C# 
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Moomoon07 Messages postés 223 Date d'inscription mercredi 31 mai 2006 Statut Membre Dernière intervention 5 mai 2014
8 sept. 2006 à 15:11
...  Jy ArRIvE PA !

Je bonderais le serveur si je vous listais mes erreurs.
MorpionMx> Peut tu me modifier un petit peu ce code  ?

MMN
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
8 sept. 2006 à 15:46
Ok, ca arrive

Mx
MVP C# 
0
Moomoon07 Messages postés 223 Date d'inscription mercredi 31 mai 2006 Statut Membre Dernière intervention 5 mai 2014
8 sept. 2006 à 16:38
Ok merci beaucoup.


Finalement je suis arrivé a enlever mes erreurs et a le faire marcher tout seul, mais j'ai fait beaucoup de bidouillage (c'est pas beau à voir). Tu ne l'a cependant pas fait pour rien parce qu'au moins ca me permet d'apprendre un peu.

Merci les admin CS sources, vous êtes des dieux !  (sans faire de lèche ...)

MMN
0
cs_Nurgle Messages postés 1642 Date d'inscription samedi 6 novembre 2004 Statut Membre Dernière intervention 28 avril 2011 3
8 sept. 2006 à 21:48
Salut,

Un peu en retard tout de même, je précise qu'il y dans le framework .NET2 un joli petit composant pour l'Asynchrone nommé BackgroundWorker qui englobe tout ça et qui évite d'avoir à manipuler à la main les threads, invoke, IAsyncResult, etc...
(très très pratique )

Voilà c'est tout

A++ et bonne continuation

<hr width="100%" size="2" />Nurgle (Antoine)
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
8 sept. 2006 à 22:00
Pourtant c'est rigolo de s'amuser avec les Threads ^^

Mx
MVP C# 
0
Moomoon07 Messages postés 223 Date d'inscription mercredi 31 mai 2006 Statut Membre Dernière intervention 5 mai 2014
9 sept. 2006 à 17:10
Si t'y a le goût, je ne serait pas contre un petit exemple avec le backgrouder worker

MMN
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
9 sept. 2006 à 17:53
Il y a un exemple dans le lien que Nurgle fournit ;)

Mx
MVP C# 
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 60
9 sept. 2006 à 18:06
Le backgroundWorker ne fait pas tout, il a ces limites...
Je ne sais pas pourquoi, mais j'utilise rarement cet object, je suis toujours avec les Threads moi ;-)

<hr size="2" />VC# forever
0
cs_Nurgle Messages postés 1642 Date d'inscription samedi 6 novembre 2004 Statut Membre Dernière intervention 28 avril 2011 3
9 sept. 2006 à 18:18
Bof, il a ses limites en effet
Mais tant qu'on ne fait pas de choses trop compliquées, il est utile.
Je dirais que tant qu'on ne manipule qu'un seul autre Thread, le BackgroundWorker suffit largement, d'autant qu'il supporte l'annulation et qu'il peut facilement rapporter sa progression.

Enfin bon, c'est un controle pour les flemmards quoi (comme moi) ;-)
(voir des IAsyncResult et des Invoke de partout me donne des boutons...)

<hr width="100%" size="2" />Nurgle (Antoine)
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
9 sept. 2006 à 19:12
C'est vrai que IAsyncResult, BeginInvoke, etc, ca semble etre des termes barbares  Et ca semble repoussant
Mais bon, une fois qu'on a pris l'habitude de s'en servir, ca pose plus de soucis

Mx
MVP C# 
0
Moomoon07 Messages postés 223 Date d'inscription mercredi 31 mai 2006 Statut Membre Dernière intervention 5 mai 2014
13 sept. 2006 à 00:52
Moi je trouve ca tout simplement génial les threads.

MMN
0
Rejoignez-nous