bonsoir.
Je suis en cours de portage d'une application console vers WPF.
La notion de thread n'a pas été simple a assimiler et je suis parti sur un backgroundworker qui fonctionne bien pour ce que je veut faire (même si pour une simple mise a jour des variables d'un thread long qui boucle indéfiniment, sur le thread UI une autre solution aurais peut être était plus propre).
Mon soucis , le processus, c'est a dire un tour de boucle était réaliser auparavant en 500ms max en mode console et a présent en WPF je suis a 12sec ! Y'a comme qui dirait un méga soucis
Visiblement en arrêt au curseur j'ai isolé dans mon thread long une boucle interne while d'environ 60 tour (c'est volontaire) qui serait la source de ce ralentissement (le reste du processus se déroule en 500ms environ).
Le soucis c'est que chaque méthode dans cette boucle se déroule sans soucis , c'est la succession des tour qui visiblement est la cause de cette lenteur. J'ai pas mal de méthode static (pas bien !) que j'ai converti en non static pour le WPF mais de ce que j'ai lu le ralentissement n'a rien a voir avec ça donc je sèche un peu. Je me suis plongé dans cette boucle pour essayer de comprendre d'ou viens le soucis mais j'ai du mal a me lancer car je ne maîtrise pas bien les systèmes de thread donc si ça se trouve je vais creuser la ou il ne faut pas.
Je pose mon code background (qui fonctionne donc.... mais lentement) juste histoire d'être certain que vous ne voyez pas d'erreur qui pourrait provoquer ce ralentissement. Pour la boucle en question elle est noyer dans trop de truc pour que j'ose la présenter ici (on a son petit orgueil) donc juste si vous avez une idée de truc classique de débutant qui ralentissent fortement une boucle while j’achète !
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 public partial class MainWindow : Window { // methode utiliser dans le thread long et parfois dans l'affichage sur le thread UI public Affichage affichage { get; set;} public PonderationClass ponderationClass { get; set; } //.... public SelectAction selection { get; set; } public Repartition repartition { get; set; } //variable présente dans méthode longue et qui serons mise a jour dans l'affichage int Jours; int Heures; int Minutes; // .... public int FreqCar; string TheTexte; public double E_Demander; private BackgroundWorker backgroundWorker; ManualResetEvent _busy = new ManualResetEvent(true); public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { backgroundWorker = new BackgroundWorker(); backgroundWorker.DoWork += BackgroundWorkerDoWork; backgroundWorker.RunWorkerCompleted += BackgroundWorkerRunWorkerCompleted; } void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e) { while (MetaBasal > 0) // juste pour que le processus long tourne indéfiniment mais la valeur de metabasal est une constante { _busy.WaitOne(Timeout.Infinite); The_Master(); // ma methode longue!!!! Thread.Sleep(50); // un intérêt ici ? Vu qu'il ne doit pas y avoir de mise a jour de l'affichage tend que la méthode n'est pas terminer // NORMALEMENT PAS D'INVOKE TEND QUE LA METHODE LONGUE N'EST PAS TERMINER Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action( delegate () { // ici une 40aine de variable a extraire du thread long pour affichage et réutilisation de ces variables pour la boucle suivante labcycle.Content = ncycle; labnyctemere.Content = Nyctemere; labJour.Content = Jours; labHeure.Content = Heures; // ... labminute.Content = Minutes; labtheTexte.Content = TheTexte; labResultat.Content = Resultat; labenergdemand.Content = E_Demander; labfreqcardeffort.Content = bpm_Card; Thread.Sleep(5); // je le pose la sans savoir si sa a un intérêt... suffisant pour mettre a jour l'affichage })); } // création d'une sortie pour la fin du backgroundworker mais qui logiquement ne devrait jamais se produire List<object> genericlist = new List<object>(); genericlist.Add(ncycle); genericlist.Add(Nyctemere); genericlist.Add(Jours); genericlist.Add(Heures); genericlist.Add(Minutes); genericlist.Add(TheTexte); genericlist.Add(Resultat); genericlist.Add(FreqCar); //........................ e.Result = genericlist; } void BackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { List<object> result = e.Result as List<object>; labcycle.Content = result[0]; //..... // Qui n'arrivera jamais.... d'ou l'utilité d'utiliser un backgroundworker du coup... } private void BtnLancer(object sender, RoutedEventArgs e) // Lance process long { if (!this.backgroundWorker.IsBusy) this.backgroundWorker.RunWorkerAsync(); } private void BtnPause(object sender, RoutedEventArgs e) // met en Pause et relance process long { if (bt1.Content.ToString() == "PAUSE") { _busy.Reset(); bt1.Content = "RESUME"; } else { _busy.Set(); bt1.Content = "PAUSE"; } } private void Btnstop(object sender, RoutedEventArgs e) // stop process long { //if (this.backgroundWorker.IsBusy) //this.backgroundWorker.CancelAsync(); _busy.Reset(); //backgroundWorker.Dispose(); // Entre les 3 je ne sais pas quoi prendre mais l'arret sauvage de mon banc d'essais n'est pas un probleme } }
Et voici l'endroit ou se trouve la boucle maudite dans mon thread long qui augmente la durée du process
voila... on bute karadoc...
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 public partial class MainWindow : Window { public void The_Master() { // ici on est dans la méthode longue // ..... // on arrive sur une boucle while qui dure près de 12sec... while (FreqCar > 0) { // une dizaine de méthode qui ne sont plus propre au thread long mais a toute l'application histoire de rendre accessible les variable a main window Metabolisme.Gl... Xeros = Meta... Xeros_MB = Me... // ... FreqCar--; } } }
bonne soirée
Partager