Bonjour tout le monde !
Travaillant actuellement sur un projet WinForm lié à une base de données, mon but étant de récupérer des médicaments en base afin de les
afficher (avec tri possible), j'ai donc compris qu'il était nécessaire de récupérer le tout de manière asynchrone afin de ne pas surcharger le thread
principal. J'ai pour habitude d'utiliser des BackgroundWorker, j'ai donc dans un premier temps créé un "poco" Medicament afin de représenter au mieux
les tables pour en faire des objets :
Ensuite j'ai ce que j'appelle des "servies", le but est de splitter au maximum le code car ça m'aide à mieux m'y retrouver donc pour un service
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 public class Medicament { public static string Id { get; set; } public string IdPrive { get; set; } public string NomCommercial { get; set; } public string IdFamille { get; set; } public string Composition { get; set; } public string Effets { get; set; } public string ContreIndications { get; set; } public decimal Prix { get; set; } public static Image Image { get; set; } }
qui représente une fonctionnalité, j'ai une interface définissant les méthodes et une classe enfant qui se charge de les compléter comme suit
(Petite précision : Vous verrez les appellations Produit et Medicament, c'est la même chose, petite maladresse de ma part) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 public interface IProduitCore { List<Medicament> GetMedicaments(); [...] }Ensuite pour afficher tous ces objets, j'ai fait un UserControl qui sera chargé d'afficher les informations des objets le tout dans un FlowLayoutPanel
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 public class ProduitCore : IProduitCore { public List<Medicament> GetMedicaments() { var medicaments = new List<Medicament>(); using (var mySqlConnection = new MySqlConnection()) { mySqlConnection.ConnectionString = Generique.MySqlConnectionString; mySqlConnection.Open(); const string query = @"SELECT Medicament.id, Medicament.nomCommercial, Medicament.prix FROM Medicament ORDER BY Medicament.nomCommercial ASC"; using (var mySqlCommand = new MySqlCommand(query, mySqlConnection)) { using (var mySqlDataReader = mySqlCommand.ExecuteReader()) { if (!mySqlDataReader.HasRows) return null; while (mySqlDataReader.Read()) { var medicament = new Medicament { IdPrive = mySqlDataReader.GetString(0), NomCommercial = mySqlDataReader.GetString(1), Prix = mySqlDataReader.GetDecimal(2) }; medicaments.Add(medicament); } return medicaments; } } } } }
donc rien de particulier j'y déclare simplement les attributs dont j'ai besoin. C'est l'étape suivante qui me pose problème, j'ai donc fait un BackgroundWorker
qui, au lancement du formulaire, va afficher un spinner de chargement puis dans le même temps va charger la liste des médicaments puis dessiner les
userControls dans le flPanel.
Initialisation et exécution du backgroundWorker :
Code exécuté par le backgroundWorker
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 frmAccueil_Load(object sender, EventArgs e) { _bgwGetAll = new BackgroundWorker { WorkerSupportsCancellation = true }; if (!_bgwGetAll.IsBusy) { fLPanelProduits.Controls.Clear(); tabControlAccueil.SelectedTab = tabPageChargement; _produitCore = new ProduitCore(); _bgwGetAll.DoWork += _bgwGetAll_DoWork; _bgwGetAll.RunWorkerCompleted += _bgwGetAll_RunWorkerCompleted; _bgwGetAll.RunWorkerAsync(); } }
Et c'est ici que le problème se pose, ma liste se charge bien, les médicaments s'affichent tous bien dans les userControls, le seul souci
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 private void _bgwGetAll_DoWork(object sender, DoWorkEventArgs e) { _medicaments = _produitCore.GetMedicaments(); if (_medicaments != null) { foreach (var items in _medicaments) { var ucProduit = new ucProduit(); ucProduit.PicProduit.Tag = items.IdPrive; ucProduit.LblNomProduit.Text = items.NomCommercial; ucProduit.LblPrixProduit.Text = $@"{items.Prix:00.00} TTC"; fLPanelProduits.BeginInvoke((MethodInvoker)delegate { fLPanelProduits.Controls.Add(ucProduit); }); } } else { Composant.MessageErreurProduits("Aucun produit n'a pu être trouvé pour cette sélection.", fLPanelProduits); } }
c'est que durant l'exécution du bgw, ma form freeze ce qui est très étrange puisque j'utilise ce même procédé ailleurs dans mon application
et le problème ne se pose pas !
Désolé pour la longueur du post, en espérant trouver une petite aide.
Merci d'avance
Cordialement.
Partager