olibara
Messages postés666Date d'inscriptiondimanche 16 décembre 2007StatutMembreDernière intervention11 mars 2010
-
16 nov. 2008 à 09:53
cs_Robert33
Messages postés834Date d'inscriptionsamedi 15 novembre 2008StatutMembreDernière intervention14 janvier 2017
-
22 nov. 2008 à 23:25
Bonjour
Si quelqu'un se sent expert en Thread il pourra peut etre m'aider
L'ideal pour expliquer serait de pouvoir envoyer un bout de code malheureusement ca reste impossible sur ce Forum
Et le copie coller de code dans le message est totalement indigeste.
(N.B. Sauf erreur de ma part je pense que c'est un des rares forum qui ne gere pas la mise en forme ou l'envoi de code lié a un message)
Explication
Le but est de ne pas lancer un traitement lourd dans le thread de l'UI mais d'avoir une mise a jour de celui ci durant le process
Je lance donc le thread secondaire avec un threadpool et j'utilise deux event pour mettre a jour ma form
En mode debug ca marche tres bien
En mode release ca bloque apres plusieurs itérations !
Si quelqu'un se sent le courage d'essayer de comprendre avec moi on essayera de trouver la bonne maniere de communiquer le bout de code concerné
Merci beaucoup pour vos aides
A voir également:
C# thread communication
C# inter thread communication - Meilleures réponses
C# communication between threads - Meilleures réponses
cs_Robert33
Messages postés834Date d'inscriptionsamedi 15 novembre 2008StatutMembreDernière intervention14 janvier 201733 21 nov. 2008 à 09:27
Bonjour,
Si j'ai bien tout compris au code, une DataTable est passée en référence aux threads (via DistMatrix ), qui y insèrent des lignes puis des cellules, en alertant la forme à chaque opération, qui elle essaye de présenter une DataView actualisée à chaque événement.
<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /??>
Je ne suis pas certain qu'une DataTable soit ThreadSafe.
Il faudrait peut être mutualisé les d'insertions et de mise à jour de la DataTable depuis des méthodes de DistMatrix et y ajouter une protection par une section critique, de manière à être certain que 2 threads n'accèdent pas en même temps.
Il est fort possible qu'en mode debug l'environnement prenne en charge certaines situations de conflit d'accès.
Bien que je n'ai pas rencontré ce genre de problème en C# c'est un phénomène bien connu en C++ natif.
Pour ma part, dans ce genre de situation je laisse la forme maitresse gérer la table (insertion, mises à jour), et je ne demande aux threads que le calcul des données.
cs_Robert33
Messages postés834Date d'inscriptionsamedi 15 novembre 2008StatutMembreDernière intervention14 janvier 201733 16 nov. 2008 à 10:02
Bonjour,
Sans voir le code il est difficile de répondre.
neamoins voici quelques pistes:
En .net les evenements ne sont pas "postés", mais executés au travers d'un delegate (le thread ne demande pas à la "form" de traiter le message, mais le traite lui-même) le traitement est donc synchrone, il faut donc que le traitement de l'evenement soit court, dans le code de la "form" fais donc attention au evenements en cascade.
Si ton traitement bloque après quelques itérations, c'est sans doute un deadlock. fais attention aux classes et aux méthodes que tu utilises, l faut qu'elles soient toutes "thread safe" sinon mets en place des sémaphores ou des sections critiques.
en esperant t'avoir donné des info utiles.
++
C# is amazing, enjoy it!
olibara
Messages postés666Date d'inscriptiondimanche 16 décembre 2007StatutMembreDernière intervention11 mars 20106 16 nov. 2008 à 10:10
Merci Robert
Voici ce que je fais
Le process appelé contient deux boucles imbriquées qui remplissent une datatable de n x n
J'ai deux event : 1 pour l'ajout de row, 1 pour l'ajout de cellule
L'event ajout de cellule affiche un compteut dans la form appellante
L'event ajout de row fait un refresh du dgv qui possede la datatable en datasource
Voci la partie du code dans la form appellante
DistMatrix dm = new DistMatrix();
dm.VV = VV;
dm.AddRow += new DistMatrix.StepRowDelegateHandler(Dist_StepRow);
dm.AddCell += new DistMatrix.StepCellDelegateHandler(Dist_StepCell);
ThreadPool.QueueUserWorkItem(new WaitCallback(Process), dm);
}
public delegate void StepCellDelegateHandler(int a, int b);
public delegate void StepRowDelegateHandler(DataTable dt);
leprov
Messages postés1160Date d'inscriptionvendredi 23 juillet 2004StatutMembreDernière intervention21 octobre 201017 17 nov. 2008 à 10:03
Comme te l'as expliqué robert, les events sont executés dans le thread qui les appelles. De plus, la msdn spécifie que l'ihm ne devrais jamais etre modifiée au travers d'un autre thread que celui qui l'a créé. A mon avis, ton code doit vraiment pas bien fonctionner. Tu devrais essayer de voir du coté de l'objet backgroundworker qui va gérer le thread secondaire pour toi
Vous n’avez pas trouvé la réponse que vous recherchez ?
olibara
Messages postés666Date d'inscriptiondimanche 16 décembre 2007StatutMembreDernière intervention11 mars 20106 17 nov. 2008 à 17:36
Salut
J'ai un problème en Release c'est un fait (en debug ca marche en "apparance" tres bien)
Mais je n'ai pas envie de jeter le BB avec l'eau du bain et j'aimerais comprendre ce que je peux ou dois faire dans le modele que j'ai utilisé pour permettre la mise a jour de mon DGV
Car si le Pavé qu'est le Backroundworker peut y arriver, il n'y a pas de raison qu'on ne puisse pas y arriver avec les outils de base !
olibara
Messages postés666Date d'inscriptiondimanche 16 décembre 2007StatutMembreDernière intervention11 mars 20106 22 nov. 2008 à 22:45
Bonsoir Robert33
Voila j'ai réussi a faire tourner la chose proprement en suivant ta sugestion de separer les operatoions de calcul qui se font dans le thread secondaire et la mise a jour de la datatable, qui se fait dans le tread principal.
Je n'ai donc plus qu'un seul event qui renvoie l'absice, l'ordonée et la valeur a ajouter dans la datatable !
La derniere chose que j'ai du chipoter c'est pour traiter proprement la fin de l'execution du Thread.
Ca a ce moment seulement je voulais activer le print ou l'export du DGV créé
Pour faire cela j'ai encore du ajouter deux events et deux delegates !!
Voici ce que ca donne :
/// <summary>
/// Event et delegate de traitement fin de Thread
/// </summary>
public delegate void StopDistDelegateHandler();
public event StopDistDelegateHandler enableBtn;
public frmDist(DataTable dt)
{
dtAdr = dt;
InitializeComponent();
}
public void ShowMatrix(bool VV)
{
DistMatrix dm = new DistMatrix();
dm.VV = VV;
dm.AddCell += new DistMatrix.StepCellDelegateHandler(Dist_StepCell);
dtDist = dm.CreateTable(dtAdr);
dgv_Dist.DataSource = dtDist;
enableBtn += new StopDistDelegateHandler(EnableBtn);