Liaison série

Résolu
pupuce54980 Messages postés 12 Date d'inscription lundi 31 juillet 2006 Statut Membre Dernière intervention 11 mai 2008 - 8 mai 2008 à 23:19
pupuce54980 Messages postés 12 Date d'inscription lundi 31 juillet 2006 Statut Membre Dernière intervention 11 mai 2008 - 11 mai 2008 à 16:14
bonjour tout le monde j'ai un petit problème de liaison série et je récupère une erreur "Safe handle has been closed"

j'ai une carte arduino diciemilia avec laquel je communique sur un port com, j'ai aussi une interface graphique sur mon application (de test), le problème c'est que ma carte est comfigurer pour envoyer une chaine de caractère en fonction de l'entrée que l'on active sur celle ci, elle me sert de capteur, donc pour éviter de bloquer mon interface graphique j'ai définie un port serie et un thread
Serialport^ s;
threading t;
t =
gcnew Threading::Thread(
gcnew Threading::ThreadStart(
this, &Form1::ExecuteLongTraitement));

j'ai fait un thread qui lit en continue les lignes que la carte envoye sur la liaison série donc le thread sera toujour bloquer sur l'instruction readline, le soucis c'est que j'ai defois besoin de couper se thread, donc j'ai fait un bouton pour arreter le thread
t->Abord();
mais quand il termine le thread, la liaison série était toujour active et bloquer sur readline et je récupère cette erreur

comment je pourrais faire pour contourné cette erreur car, si je ne lis rien sur la liaison série que je termine le thread je n'ai pas d'erreur meme si j'oublie de fermé la liaison série

private

: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{

if(t->IsAlive)
{

t->Abort();
label1->Text=
"thread terminer";
label1->Update();
}

else{
t =
gcnew Threading::Thread(
gcnew Threading::ThreadStart(
this, &Form1::ExecuteLongTraitement));
t->Start();
label1->Text=
"thread commencer : capteur";
label1->Update();
}
}

void ExecuteLongTraitement()
{
String^ line;
s.Open();

while(1)
{
line=s.ReadLine();

if(line=
"a\r")
{

this->Invoke(ProgressBarDelegate);
}
}

en fait j'aimerais pouvoir killer mon thread proprement sans erreur merci

4 réponses

cs_akim77 Messages postés 73 Date d'inscription lundi 12 avril 2004 Statut Membre Dernière intervention 17 septembre 2008 4
9 mai 2008 à 23:50
Salut,

Je ne connait pas bien C++.Net mais je sais qu'il faut que le thread se termine seul.
La méthode simpliste serai d'utiliser une variable globale en remplaçant
while(1) par while(variable_globale) et de mettre variable_globale=0;
quand tu veux que le thread se termine.
Je l'ai déja fait et ça marche mais c'est pas trop "pro" .

Une méthode plus pro serai d'adapter de code C# décrit ici:
http://msdn.microsoft.com/fr-fr/library/7a2f3ay4(VS.80).aspx


Une question: Où as-tu acheté ta carte arduino diciemilia ?

@+
Akim
3
pupuce54980 Messages postés 12 Date d'inscription lundi 31 juillet 2006 Statut Membre Dernière intervention 11 mai 2008
11 mai 2008 à 16:12
voila ma source, pour contourné se soucis, j'ai mis une variable global dans ma classe qui s'appelle j, quand je veut tuer mon processus c pas instantanné mais bon c pas si long que ca.

en fait je met cette variable à 1 j'attent 200 milliseconde et je le tue, tandis que mon thread mon thread lit la liaison série avec un timeout de 100 milliseconde, donc toute les 100 milliseconde je peut vérifié l'etat de cette variable, si elle est a 1 je met mon thread dans en attente de 1 seconde. donc le temps de mettre la variable a 1 attendre 2 lecture de la liaison série , pendant se temps la le thread c mis en attente et pas sur une lecture de la liaison serie qui provoque cette erreur, alors la je eput le tuer sans soucis et sans erreur.




private



: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{


if
(t->IsAlive)
{
j=1;
System::Threading::Thread::Sleep(200);
t->Abort();
s.Close();
label1->Text=

"thread terminer"
;
label1->Update();
}


else
{
t =

gcnew
Threading::Thread(

gcnew
Threading::ThreadStart(

this
, &Form1::ExecuteLongTraitement));
j=0;
t->Start();
label1->Text=

"thread commencer : capteur"
;
label1->Update();
}
}


void
ExecuteLongTraitement()
{
String^ line;
clock_t start,start2,start3;
start=clock();
start2=clock();
start3=clock();
s.Open();
s.ReadTimeout=100;


while
(1)
{
i++;


try
{
line=s.ReadLine();
}


catch
(TimeoutException^ ex)
{
}


if
(j==1)
{
System::Threading::Thread::Sleep(1000);
}


if
(line==

"A\r"
)
{


if
((clock()-start)>200)
{


this
->Invoke(ProgressBarDelegate);
start=clock();
}


else

{
start=clock();
}
}


if
(line==

"B\r"
)
{


if
((clock()-start2)>200)
{


this
->Invoke(ProgressBarDelegate2);
start2=clock();
}


else

{
start2=clock();
}
}


if
(line==

"C\r"
)
{


if
((clock()-start3)>200)
{


this
->Invoke(ProgressBarDelegate3);
start3=clock();
}


else

{
start3=clock();
}
}
line=

""
;
}
}
3
pupuce54980 Messages postés 12 Date d'inscription lundi 31 juillet 2006 Statut Membre Dernière intervention 11 mai 2008
10 mai 2008 à 08:26
heu j'ai trouvé aussi une solution en bidouillant avec une variable global et en mettant un timeout sur la liaison série quand je l'initialise, un time out de 10 miliseconde, et ensuite je regarde si une variable global n'est pas a 1, si elle est a un je bloque le thread de 1 seconde le temps pour que mon processus père le tue,

pour la carte arduino diciemilia, c les profs qui me suivent dans mon projet qui l'ont commander a partir du site www.arduino.cc, il y a un seul revendeur en france qui les vendent.

je reviendrais mettre ma source pour la résolution de mon problème d'ici 14 H
0
pupuce54980 Messages postés 12 Date d'inscription lundi 31 juillet 2006 Statut Membre Dernière intervention 11 mai 2008
11 mai 2008 à 16:14
http://82.240.238.211/catalog/index.php?cPath=27_35&language=fr





akim : voici le lien pour commander une carte arduino diciemilia
0
Rejoignez-nous