Bonjour,
J'ai un souci avec mon programme, j'ai une consommation mémoire croissante que je ne comprends pas du tout. J'ai analysé mon code mais je ne trouve aucune piste.
A son lancement mon programme lance un thread qui me remplit un listview en mode virtuel :
Procédure que le thread appelle :
Quand le remplissage de la liste est terminé, on appelle la procédure StartThreads qui me lance deux nouveaux threads, un qui vérifie la connexion à un serveur de fax toutes les 30s :
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
17 private void UpdateListeFax() { faxes = zf.GetFaxes(config.FAX_emetteur_nom); if (listeCache == null) listeCache = new List<ListViewItem>(); this.Invoke(new MethodInvoker(delegate { listfax.Items.Clear(); listfax.VirtualMode = true; listfax.HeaderStyle = ColumnHeaderStyle.Clickable; listfax.VirtualListSize = faxes.Count; })); retourftp = true; UpdaterState = new UpdateState(maj_state_liste); _AddFax = new AddFax(AddListeFax); StartThreads(); // lance les threads de traitement }
Un autre qui regarde toutes les 500 ms s'il faut envoyer des fax au serveur et qui vérifie le statut des fax existants :
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
17
18
19
20
21
22
23
24
25
26
27
28 private void server_check() { while (!Tcancel) { if (!zf.CheckServer(out zf_err)) { StopConnection(); reconnectzetafax(); } else { // On met à jour les stats zf.UpdateStats(faxes); this.Invoke(new MethodInvoker(delegate { lock (this) { // On affiche les stats lbstat.Text = String.Format("Fax en attente : {0} - Fax envoyés : {1} - Fax échoués : {2} - Total des fax : {3}", zf._GlobalState.fax_waiting, zf._GlobalState.fax_ok, zf._GlobalState.fax_failed, zf._GlobalState.fax_all); } })); } Threading.Thread.Sleep(TimerDelay2); } Logger("Fin du thread 2"); }
maj_state est la procédure qui vérifie le statut de chaque fax :
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
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95 private void check() { fax newfax; bool sended, verif_file; string fic; while (!Tcancel) { // On traite les fichiers .cfg foreach (string folder in lstdossiers) { if (IO.Directory.Exists(folder)) { foreach (string FI in IO.Directory.GetFiles(folder, "*.cfg", IO.SearchOption.TopDirectoryOnly)) { Logger("Fichier " + FI + " trouvé"); Logger("Vérification de l'accès au fichier"); if (CheckFile(FI)) { sended = false; // On récupère les informations utiles Logger("Récupération des valeurs du fichier pour le traitement du fax"); if (ini.RecupererValeur("Envoi", "Protocole", FI).ToUpper() == "FAX" | ini.RecupererValeur("Envoi", "Protocole", FI).ToUpper() == "HPRIMMEDECIN") { newfax = new fax(); newfax.Id = Guid.NewGuid(); newfax.dateajout = new IO.FileInfo(FI).CreationTime; newfax.to = new string[,] { {ini.RecupererValeur("Envoi", "Medecin", FI), ini.RecupererValeur("Envoi", "Telephone", FI)}}; fic = ini.RecupererValeur("Envoi", "Fichier", FI); verif_file = false; Logger("Nom fichier joint : " + fic); for (int n = 0; n < config.FAX_emetteur_hostnamesfile.Count; n++) { Logger("Vérification de l'accés au fichier " + config.FAX_emetteur_hostnamesfile[n] + fic); verif_file = CheckFile(config.FAX_emetteur_hostnamesfile[n] + fic); if (verif_file) { fic = config.FAX_emetteur_hostnamesfile[n] + fic; break; } Threading.Thread.Sleep(10); } if (verif_file) { newfax.files = new string[] { fic }; newfax.From = config.FAX_emetteur_nom; newfax.Dossier = ini.RecupererValeur("Envoi", "NumDossier", FI); newfax.CodeMedecin = ini.RecupererValeur("Envoi", "CodeMedecin", FI); newfax.FaxPatient = ini.RecupererValeur("Envoi", "FaxPatient", FI); newfax.RetourAs400 = false; Logger("Envoi du fax au serveur"); if (zf.SendMessage(ref newfax, out zf_err)) { do { zf.GetInfosFax(true, ref newfax, out zf_err); Threading.Thread.Sleep(10); } while (newfax.status == null); Logger("Id serveur du fax : " + newfax.body + ", Id SendFax : " + newfax.Id); IO.File.Delete(FI); this.Invoke(_AddFax, newfax); sended = true; Logger("Envoi OK"); } } } else { zf_err = "HostName non trouvé pour le fichier joint"; sended = false; } if (!sended) { ini.StockerValeur("Envoi", "Erreur", zf_err, FI); Logger("Envoi échoué : " + zf_err); if (IO.File.Exists(FI + ".bad")) IO.File.Delete(FI + ".bad"); IO.File.Move(FI, FI + ".bad"); } } } } } // On met à jour le status des fax if(zf.CheckNewStatus()) maj_state(); Threading.Thread.Sleep(TimerDelay); } Logger("Fin du thread 1"); }
Le type 'fax' est une structure publique :
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
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 private void maj_state() { string f_oldstate=""; int max = faxes.Count-1; fax newfax; for (int i = max ; i >= 0; i--) { if (Tcancel) break; newfax = faxes[i]; f_oldstate = newfax.status; zf.GetInfosFax(true, ref newfax, out zf_err); if (newfax.status == null | ((DateTime.Now - newfax.dateajout).TotalDays > config.histo_jours) & config.histo_jours > 0) { Logger("fax " + newfax.body + " ( id = " + newfax.Id + " ) plus disponible ou trop ancien, suppression de la liste"); // int n = RetreiveFaxIndex(f); Logger("Index du fax dans la liste : " + i); RemoveFax(i, true); } else { if (!f_oldstate.Equals(newfax.status)) { switch (newfax.status.ToUpper()) { case "OK": case "FAILED": if (!newfax.RetourAs400 & retourftp) { Logger("Retour AS400 pour le fax " + newfax.body); if (!AS400.sendretourfax_batch( config.FTP_user, config.FTP_pass, config.FTP_ip, "LAB400EDT.LIB", "FAXJRL", AS400.CreateRetFile(newfax), out zf_err)) { this.Invoke(new MethodInvoker(delegate() { //MessageBox.Show("Un problème FTP est survenu lors du retour vers l'ISeries." + Environment.NewLine + // "Les retours sont désactivés tant que " + Application.ProductName + " ne sera pas redémarré." + Environment.NewLine + Environment.NewLine + // "Erreur FTP : " + zf_err, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); this.Text = Application.ProductName + " v" + Application.ProductVersion + " - Retour FTP en erreur"; })); retourftp = false; } else { newfax.RetourAs400 = true; } } break; } faxes[i] = newfax; this.Invoke(UpdaterState, faxes[i].status, i); } } } }
En gros, mon programme au lancement consomme environ 12 K, je me retrouve avec une conso de 200 000 K au bout d'une demi journée d'utilisation.
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 public struct fax { public Guid Id; public DateTime dateajout; public string body; public string From; public string[,] to; public string[] files; public string status; public string Dossier; public string FaxPatient; public string CodeMedecin; public bool RetourAs400; }
Les procédures liées à l'instance 'zf' ne sont selon moi pas en cause.
Voici les procédures liées au traitement du listView :
Vraiment, si je demande de l'aide sur le forum c'est que je sèche totalement sur cette consommation mémoire abusive, j'ai consulté plusieurs sites pour me familiariser avec la gestion mémoire en .NET mais cela ne m'a pas aidé à solutionner mon problème.
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
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 void listfax_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e) { if (listeCache != null && e.StartIndex >= firstitem && e.EndIndex <= firstitem + listeCache.Count) { return; } firstitem = e.StartIndex; int length = e.EndIndex - e.StartIndex + 1; listeCache = new List<ListViewItem>(); for (int n = 0; n < length; n++) { listeCache.Add(FaxToListe(faxes[e.StartIndex + n])); } } void listfax_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) { try { if (listeCache != null && e.ItemIndex >= firstitem && e.ItemIndex < firstitem + listeCache.Count) { e.Item = listeCache[e.ItemIndex - firstitem]; } else { e.Item = FaxToListe(faxes[e.ItemIndex]); } } catch (ArgumentOutOfRangeException) { Logger("Item " + e.ItemIndex + " n'existe plus."); e.Item = null; } }
Si vous avez besoin d'autres infos sur mon code ou sur le programme, faites-le moi savoir.
Partager