classe thread,classe delegue
bonjour nbcsharp
pour ne pas faire des "trucs" et aussi parce que tu parles de reordonner un peu les choses.
1/Inconvenient d'utiliser une classe Thread
-ne permet pas de passer des parametres.
-il faut utiliser des parametres globaux.
2/ "Aspect" peu connu des Delegues
-un delegue s'execute toujours dans un thread different ,eh oui.
-Au lieu d'utiliser un "thread" pour faire du "threading" on peut utiliser simplement la "bete" delegue "explicitement avec sa methode BeginInvoke" qui fait tres bien du threading
-on peut passer des parametres.
-quand on utilise un delegue on fait du threading sans le savoir (Mr Jourdain fait de la prose sans le savoir)
2/Mise à jour de l'UI
- utiliser egalement un delegue "auxiliaire" charge de la maj des controles.
- utiliser la methode InvokeRequired des controles,peu connue.
Pour illustrer ce qui precede voici le code repris (les appels à ton api sont en "comments" puisque je ne les ai pas)
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 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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
//Remarque1: Definition d'un Delegue
//l'appel "par defaut" à un delegue equivaut
//à utiliser NomDelegue.BeginInvoke avec parametres
//BeginInvoke "asynchrone" s'execute toujours dans un thread separe
//----------------------------------------------------
//Class monDelegueDelegate
// Inherits MulticaseDelegate
// Sub Invoke(digits As Integer)
// Sub BeginInvoke(param1 As type1,param2 as type2,etc..., _
// callback As AsyncCallback, asyncState As Object)
// Sub EndInvoke(result As IAsyncResult)
//End Class
//--------------------------------------------------------------------------
//Remarque2: sur les Methodes des Controles
// Invoke,BeginInvoke,EndInvoke,InvokeRequired
//qui utilise un Delegue comme parametre
//--------------------------------------------------------------------------
//Class System.Windows.Forms.Control
// Overloads Function Invoke(method As Delegate) As Object
// NotOverridable Overloads Function Invoke(method As Delegate, _
// args() As Object) As Object
// Overloads Function BeginInvoke(method As Delegate) As IAsyncResult
// NotOverridable Overloads Function BeginInvoke(method As Delegate, _
// args() As Object) As IAsyncResult
// NotOverridable Function EndInvoke(asyncResult As IAsyncResult) As Object
//End Class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace MyPlugin {
public partial class Form1 : Form
{
//Delegue permet de passer des parametres
//Appel à classe thread ne le permet pas(il faut parametres globaux)
//Passage de parametres en utilisant "explicitement" BeginInvoke
//
public delegate void dlgGReconnect(string usr, string pwd);
//
//Delegue auxiliaire charge de la maj de l'UI
//appele "asynchroniquement
//
public delegate void dlgMiseAjourUI(int counter);
public Form1()
{
InitializeComponent();
}
private void OnLoaded(object sender, EventArgs e)
{
//Application.Idle -= new EventHandler(OnLoaded);
//this.myAPI.Reconnect(usr, pwd); // Appel dans le thread Form mais long à traiter... Donc essai avec Thread :
//Thread reco = new Thread(new ThreadStart(DoReconnect));
//reco.IsBackground = true;
//reco.Start();
}
private void DoReconnect()
{
// Le thread accède à myAPI, usr, pwd mais ce sont pas des contrôles...
//this.myAPI.Reconnect(usr, pwd);
//this.Invoke(new MethodInvoker(DoThings));
}
private void DoReconnectBIS(string usr, string pwd)
{
//Le thread accède usr, pwd sont des parametres internes...
//this.myAPI.Reconnect(usr, pwd);
//this.Invoke(new MethodInvoker(DoThingsBis));
DoThingsBis();
}
private void DoThings()
{
//FillListView(myAPI.GetList());
// et les trucs suivants
}
//Version Revise de DoThings avec Maj de l'UI
private void DoThingsBis()
{
//
//Simple Compteur mais ca peut etre des variables de FillListView
//
int counter=0;
//Appel maj de UI
MiseAjourUI(counter);
//FillListView(myAPI.GetList());
for (int j=0;j<1000000000;j++)
{
counter = j;
}
//Appel maj de UI
MiseAjourUI(counter);
}
//
//Sub de Maj des controles de l'interface UI
//
private void MiseAjourUI(int counter)
{
//L'appel vient de UI directement(normal)
if (!this.InvokeRequired)
{
this.textBox1.Text= counter.ToString();
this.label1.Text = counter.ToString();
this.progressBar1.Value = counter;
}
//Non l'appel vient d'un autre thread
// s'invoke elle-meme mais "asynchroniquement"
// par le biais du Delegue auxiliaire maj UI
else
{
dlgMiseAjourUI objMiseAjourUI = MiseAjourUI;
this.BeginInvoke(objMiseAjourUI,new object[]{counter});
}
}
//On demarre la tache "worker" ici
private void button1_Click(object sender, EventArgs e)
{
//ceci est une autre facon de faire
//Utilise Appel par defaut "explicite asynchrone" BeginInvoke
this.textBox1.Text = "";
this.label1.Text = "";
this.progressBar1.Minimum = 0;
this.progressBar1.Maximum = 100;
string usr = "ALI";
string pwd = "MOMO";
dlgGReconnect recoBis = DoReconnectBIS;
recoBis.BeginInvoke(usr, pwd, null, null);
}
}
} |
A propos des parametres null,null.Grace à eux on peut definir des methodes de rappel(callback) du genre avertissement "tache terminee....".
Il ne faut pas faire des "trucs" mais faire un code propre.....
bon code