BackgroundWorker provoquant un freeze GUI
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 :
Code:
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; }
} |
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
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:
1 2 3 4 5 6
|
public interface IProduitCore
{
List<Medicament> GetMedicaments();
[...]
} |
Code:
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;
}
}
}
}
} |
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
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:
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();
}
} |
Code exécuté par le backgroundWorker
Code:
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);
}
} |
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
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.