littlekenny
Messages postés43Date d'inscriptionmardi 25 février 2003StatutMembreDernière intervention10 septembre 2009
-
28 févr. 2008 à 17:34
littlekenny
Messages postés43Date d'inscriptionmardi 25 février 2003StatutMembreDernière intervention10 septembre 2009
-
4 mars 2008 à 09:51
Salut,
M'étant basé sur l'article de MorpionMx (Opérations cross-threads - utilisation des délégations synchrones / asynchrones), j'aimerais fermer mon thread secondaire (traitement qui peut devenir long et lourd) via un bouton ou popup lié à mon thread principal. Une fois mon thread secondaire lancé, mon interface principale est cependant bloquée jusqu'à la fin de l'exécution du thread secondaire (qu'il soit asynchrone ou pas, ça ne change rien).
<hr size="2" width="100%" />// mon thread secondaire
private Thread threadLoadReport=null;
...
//je lance mon thread secondaire à partir de la forme qui contient le bouton qui devrait être utilisé pour tuer (abord) ce thread.
threadLoadReport = new Thread(new ThreadStart(ExecuteThreadReport));
threadLoadReport.Priority = ThreadPriority.Highest;
threadLoadReport.Start();
...
private void ExecuteThreadReport()
{
IAsyncResult iar=this.BeginInvoke(new DelExecuteReport(ExecuteReport), lastReportOpened);
//lancement de l'exécution lourde, contenue dans la procédure ExecuteReport(string str)
this.EndInvoke(iar);
}
...
//le code derrière le bouton pour tuer mon thread secondaire est simple:
if (threadLoadReport != null)
{
threadLoadReport.Abort();
threadLoadReport = null;
}
<hr size="2" width="100%" />Pour résumé, je ne comprends pas pourquoi mon interface principale est bloquée lorsque je lance mon thread secondaire. J'aimerais avoir la possibilité de garder la main sur celle-ci.
Un super grand merci d'avance, ça me dépannerait beaucoup.
littlekenny
Messages postés43Date d'inscriptionmardi 25 février 2003StatutMembreDernière intervention10 septembre 2009 4 mars 2008 à 09:51
Je crois avoir trouvé une solution:
private Thread threadLoadReport = null; //thread pour afficher mon rapport
private Thread threadStop = null; //thread pour popup, pour arrêter threadLoadReport
...
threadStop = new Thread(new ThreadStart(ExecuteThreadStop));
threadStop.Name = "stop";
threadStop.Start();
threadLoadReport = new Thread(new ThreadStart(ExecuteThreadReport));
threadLoadReport.Name= "Execute";
threadLoadReport.Priority = ThreadPriority.Highest;
threadLoadReport.IsBackground = true;
threadLoadReport.Start();
...
private void ExecuteThreadStop()
{
frmStop = new FrmStop(); //mon popup qui va me servir à stopper le chargement de mon rapport (using to abord the thread threadLoadReport).
frmStop.ShowDialog(); //j'utilise un showdialog et pas un show, sinon le popup disparait à la fin du thread (vu qu'ils sont liés)
}
Comme vous pouvez le voir, je n'utilise pas d'invoke dans mon second thread (ExecuteThreadStop()), cela répond bien à ma question-réponse de mon post précédent sur la méthode invoke. Mon popup n'est ainsi pas lié au thread principal et est lancé via un autre thread. Le plus lourd du travail est fait, il ne me reste plus qu'à aborder le chargement du premier thread et c'est bon.
littlekenny
Messages postés43Date d'inscriptionmardi 25 février 2003StatutMembreDernière intervention10 septembre 2009 29 févr. 2008 à 09:05
Merci pour vos réponses mais ça ne fonctionne pas :
> [auteur/LASSAAD83/760533.aspx lassaad83] : ExecuteReport(string str) est ma procédure qui charge un crystal report dans un viewer.
En gros, j'ai ceci comme code dedans :
crystalReport.ReportSource = crReportDocument; où crReportDocument est un rapport Crystal. Selon les paramètres introduits, le temps d'exécution est plus ou moins long (de 2 à 30sec).
> [auteur/MORPIONMX/5912.aspx MorpionMx] : J'ai essayé ce qui a été fait dans l'exemple mais ça ne fonctionne pas:
...
threadLoadReport = new Thread(new ThreadStart(ExecuteThreadReport));
threadLoadReport.IsBackground = true; // je l'ai rajouté
threadLoadReport.Start();
...
private void ExecuteThreadReport()
{
//pas de boucle
IAsyncResult
iar = this.BeginInvoke(new DelExecuteReport(ExecuteReport), lastReportOpened); //traitement lourd
Thread.Sleep(1000); //pause ridicule par rapport au traitement
this.EndInvoke(iar);
}
En appuyant comme un forcené sur mon bouton stop, on dirait qu'il peut de temps en temps recevoir l'event click. A mon avis, ça correspond au temps de pause d'une seconde.
cs_coq
Messages postés6349Date d'inscriptionsamedi 1 juin 2002StatutMembreDernière intervention 2 août 2014101 1 mars 2008 à 19:07
Salut,
Que fait tu après le lancement du thread ?
Le problème se pose t'il aussi si tu neutralises la génération du rapport et que tu la remplaces par une attente longue ?
littlekenny
Messages postés43Date d'inscriptionmardi 25 février 2003StatutMembreDernière intervention10 septembre 2009 3 mars 2008 à 14:48
> coq : "Que fait tu après le lancement du thread ?" Pour l'instant, rien.
J'essaye, via un popup avec un bouton (lancé dans un autre thread), si le programme me redonne la main pendant le chargement (un peu comme la méthode annuler le chargement dans Toad). Rien de concluant pour l'instant.
"Le problème se pose t'il aussi si tu neutralises la génération du rapport et que tu la remplaces par une attente longue ?" Si je remplace la génération du rapport par un sleep, ça fonctionne. Je me demande si le problème n'est pas lié à la méthode invoke. J'avais lu dans un de tes posts que cette méthode créait une instance de la procédure appelée dans le thread principal (si je ne me trompe pas). Mon problème vient peut-être de là.
Je vais encore tester ça. Si je trouve quelque chose, je le posterai tantôt.
De même, si vous avez des idées, n'hésitez pas à partager. Merci d'avance.