OVH Cloud OVH Cloud

[Vb.net 2005] - Threading.Thread

17 réponses
Avatar
TroXsA
Bonjour a tous
je sais pas trop me servire du System.Threading.Thread tout ce que je sais
faire avec c'est ça :


MyThread = New System.Threading.Thread(AddressOf NomFunction"Ou"Sub)
' Call sub procedure
MyThread.Start

J'ai fais une petite application avec plusieurs onglet
l'onglet 1 c'est la partie parametrage, onglet 2 c'est l'execution, et
l'onglet 3 c'est la partie pour voir si tout c'est bien executé

Le probleme ce pause dans l'onglet 2, l'ors de l'execution diverse
l'application ce bloque sur cet onglet je ne peu en changer durent le
traitement, il faut que toute les executions soit fini pour pouvoir naviguer
dans les Onglets

Peut on utiliser un system.threading.thread de facon que l'application ne ce
fige pas sur un onglet ?
ou alors je l'utilise mal ?


Merci

10 réponses

1 2
Avatar
Julien Bakmezdjian [MS]
Bonsoir,

C'est tout à fait possible, et même recommandé.
Il "suffit" de placer le code de l'exécution dans la fonction de départ du
second thread. Ainsi, le thread de l'UI sera libéré et dispo pour
l'utilisateur !
La fonction de travail aura cependant toujours accès aux variables de la
classe et pourra ainsi mettre à jour l'affichage régulièrement.

Cordialement,

Julien Bakmezdjian

"TroXsA" a écrit dans le message de news:
dctbfl$uvb$
Bonjour a tous
je sais pas trop me servire du System.Threading.Thread tout ce que je sais
faire avec c'est ça :


MyThread = New System.Threading.Thread(AddressOf
NomFunction"Ou"Sub)
' Call sub procedure
MyThread.Start

J'ai fais une petite application avec plusieurs onglet
l'onglet 1 c'est la partie parametrage, onglet 2 c'est l'execution, et
l'onglet 3 c'est la partie pour voir si tout c'est bien executé

Le probleme ce pause dans l'onglet 2, l'ors de l'execution diverse
l'application ce bloque sur cet onglet je ne peu en changer durent le
traitement, il faut que toute les executions soit fini pour pouvoir
naviguer dans les Onglets

Peut on utiliser un system.threading.thread de facon que l'application ne
ce fige pas sur un onglet ?
ou alors je l'utilise mal ?


Merci








Avatar
TroXsA
Je comprend pas trop :o/

Il faut creer deux thread ?
Aurais tu un exemple a me donner ?


Merci d'avance
Avatar
Julien Bakmezdjian [MS]
Bonjour,

Voyez l'exemple à :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemthreadingthreadclasstopic.asp.

Dans votre code, à l'endroit où vous souhaitez lancer le début du
"traitement", vous créez et lancer le second thread (le premier thread étant
le thread de l'UI, celui lancé automatiquement au démarrage de votre
application) :

Dim t As New Thread(AddressOf ThreadProc)
t.Start()

ThreadProc est une Sub définie un peu plus haut dans l'exemple, qui va
contenir le "traitement" :

Public Shared Sub ThreadProc()
'Code pour l'exécution
End Sub

J'espère que cela peut t'aider,

Cordialement,

Julien Bakmezdjian


"TroXsA" a écrit dans le message de news:
dda75k$i1i$
Je comprend pas trop :o/

Il faut creer deux thread ?
Aurais tu un exemple a me donner ?


Merci d'avance



Avatar
TroXsA
J'ai bien compris l'exemple qui ce trouve que le msdn :) (enfin je crois)
ça fonctionne bien quand je fait leurs exemple dans un nouveau projet

Mais ça ne fonctionne pas quand je l'utilise dans mon code ! :(
je dit pas que le thread en lui meme en fonctionne pas mais de l'utiliter
que j'en fait


Voila mon code

Private Sub BtnExeQueue_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles BtnExeQueue.Click
MyThread = New Threading.Thread(AddressOf TaskExecutShell)
MyThread.Start()
Dim SubItemLvTrack As New ListViewItem
Do While Not (LvQueue.Items.Count) = 0
LvQueue.Items.Item(0).SubItems.Item(2).Text = "En execution"
LvQueue.Refresh()
TaskCommmand = names.Peek.ToString()
TaskExecutShell()
SubItemLvTrack = LvTrack.Items.Add(LvQueue.Items.Item(0).Text)
SubItemLvTrack.SubItems.Add(LvQueue.Items.Item(0).SubItems.Item(1).Text)
SubItemLvTrack.SubItems.Add(ListViewResultat)
LvQueue.Items.RemoveAt(0)
names.Dequeue()
If names.Count = 0 Then
Exit Do
End If
Loop
names.Clear()
End Sub


----------------- puis -----------------


Public Shared Sub TaskExecutShell()
Dim TasksProcess As New Process
With TasksProcess
With .StartInfo
.UseShellExecute = False
.RedirectStandardOutput = True
.FileName = Environ("comspec")
.CreateNoWindow = True
.Arguments = "/c " & TaskCommmand
End With
.Start()
ListViewResultat = TasksProcess.StandardOutput.ReadToEnd()
End With
End Sub

Je comprend que "TaskExecutShell" n'est pas bloquant pour mes onglets (ou le
deplacement de la fenetre) car le thread est bien actif !
ça doit etre dans l'evenementiel du bouton qui doit etre bloquant ?

A bientot
Avatar
Julien Bakmezdjian [MS]
Bonjour,

Après avoir lancé le thread, vous ne devez plus rien faire dans le thread
principal... MyThread.Start doit être la dernière instruction de
BtnExeQueue_Click.
A ce que j'imagine, vous, vous faites une boucle pour savoir si justement
l'exécution est terminée...
C'est au thread de l'exécution de mettre à jour l'affichage... et
éventuellement de lancer un événement (vous devez créer un événement custo)
qui va déclencher une action dans le thread principal... puis le thread
d'exécution se termine.

Julien Bakmezdjian

"TroXsA" a écrit dans le message de news:
ddae1l$m47$
J'ai bien compris l'exemple qui ce trouve que le msdn :) (enfin je crois)
ça fonctionne bien quand je fait leurs exemple dans un nouveau projet

Mais ça ne fonctionne pas quand je l'utilise dans mon code ! :(
je dit pas que le thread en lui meme en fonctionne pas mais de l'utiliter
que j'en fait


Voila mon code

Private Sub BtnExeQueue_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles BtnExeQueue.Click
MyThread = New Threading.Thread(AddressOf TaskExecutShell)
MyThread.Start()
Dim SubItemLvTrack As New ListViewItem
Do While Not (LvQueue.Items.Count) = 0
LvQueue.Items.Item(0).SubItems.Item(2).Text = "En execution"
LvQueue.Refresh()
TaskCommmand = names.Peek.ToString()
TaskExecutShell()
SubItemLvTrack = LvTrack.Items.Add(LvQueue.Items.Item(0).Text)
SubItemLvTrack.SubItems.Add(LvQueue.Items.Item(0).SubItems.Item(1).Text)
SubItemLvTrack.SubItems.Add(ListViewResultat)
LvQueue.Items.RemoveAt(0)
names.Dequeue()
If names.Count = 0 Then
Exit Do
End If
Loop
names.Clear()
End Sub


----------------- puis -----------------


Public Shared Sub TaskExecutShell()
Dim TasksProcess As New Process
With TasksProcess
With .StartInfo
.UseShellExecute = False
.RedirectStandardOutput = True
.FileName = Environ("comspec")
.CreateNoWindow = True
.Arguments = "/c " & TaskCommmand
End With
.Start()
ListViewResultat = TasksProcess.StandardOutput.ReadToEnd()
End With
End Sub

Je comprend que "TaskExecutShell" n'est pas bloquant pour mes onglets (ou
le deplacement de la fenetre) car le thread est bien actif !
ça doit etre dans l'evenementiel du bouton qui doit etre bloquant ?

A bientot



Avatar
TroXsA
Ok, j'ai bien compris cette fois :) ça devrais aller maintenant

Merci beaucoup Julien B
Bonne fin de journée !


"Julien Bakmezdjian [MS]" a écrit dans le
message de news:
Bonjour,

Après avoir lancé le thread, vous ne devez plus rien faire dans le thread
principal... MyThread.Start doit être la dernière instruction de
BtnExeQueue_Click.
A ce que j'imagine, vous, vous faites une boucle pour savoir si justement
l'exécution est terminée...
C'est au thread de l'exécution de mettre à jour l'affichage... et
éventuellement de lancer un événement (vous devez créer un événement
custo) qui va déclencher une action dans le thread principal... puis le
thread d'exécution se termine.

Julien Bakmezdjian

"TroXsA" a écrit dans le message de news:
ddae1l$m47$
J'ai bien compris l'exemple qui ce trouve que le msdn :) (enfin je crois)
ça fonctionne bien quand je fait leurs exemple dans un nouveau projet

Mais ça ne fonctionne pas quand je l'utilise dans mon code ! :(
je dit pas que le thread en lui meme en fonctionne pas mais de l'utiliter
que j'en fait


Voila mon code

Private Sub BtnExeQueue_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles BtnExeQueue.Click
MyThread = New Threading.Thread(AddressOf TaskExecutShell)
MyThread.Start()
Dim SubItemLvTrack As New ListViewItem
Do While Not (LvQueue.Items.Count) = 0
LvQueue.Items.Item(0).SubItems.Item(2).Text = "En execution"
LvQueue.Refresh()
TaskCommmand = names.Peek.ToString()
TaskExecutShell()
SubItemLvTrack = LvTrack.Items.Add(LvQueue.Items.Item(0).Text)
SubItemLvTrack.SubItems.Add(LvQueue.Items.Item(0).SubItems.Item(1).Text)
SubItemLvTrack.SubItems.Add(ListViewResultat)
LvQueue.Items.RemoveAt(0)
names.Dequeue()
If names.Count = 0 Then
Exit Do
End If
Loop
names.Clear()
End Sub


----------------- puis -----------------


Public Shared Sub TaskExecutShell()
Dim TasksProcess As New Process
With TasksProcess
With .StartInfo
.UseShellExecute = False
.RedirectStandardOutput = True
.FileName = Environ("comspec")
.CreateNoWindow = True
.Arguments = "/c " & TaskCommmand
End With
.Start()
ListViewResultat = TasksProcess.StandardOutput.ReadToEnd()
End With
End Sub

Je comprend que "TaskExecutShell" n'est pas bloquant pour mes onglets (ou
le deplacement de la fenetre) car le thread est bien actif !
ça doit etre dans l'evenementiel du bouton qui doit etre bloquant ?

A bientot







Avatar
TroXsA
Je doit ne pas etre doué sur le fonctionnement du thread
je croyais avoir tout compris enfait j'ai rien absorbé

Dans mon bouton_Click j'ai mis ma procedure Public Sub EvenBoutonExe
ce qui donne ceci

Private Sub BtnExeQueue_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles BtnExeQueue.Click
Dim t As New Threading.Thread(AddressOf EvenBoutonExe)
t.Start()
End Sub

J'execute le tout ... et ... (Erreur) sur
LvQueue.Items.Item(0).SubItems.Item(2).Text = "En execution"

******************************************************************************
Opération inter-threads non valide : le contrôle 'LvQueue' a fait l'objet
d'un accès à partir d'un thread autre que celui sur lequel il a été créé.
******************************************************************************

L'exception System.InvalidOperationException n'a pas été gérée
Message="Opération inter-threads non valide : le contrôle 'LvQueue' a fait
l'objet d'un accès à partir d'un thread autre que celui sur lequel il a été
créé."
Source="System.Windows.Forms"
StackTrace:
à System.Windows.Forms.Control.get_Handle()
à
System.Windows.Forms.ListView.ListViewNativeItemCollection.DisplayIndexToID(Int32
displayIndex)
à
System.Windows.Forms.ListView.ListViewNativeItemCollection.get_Item(Int32
displayIndex)
à System.Windows.Forms.ListView.ListViewItemCollection.get_Item(Int32
index)
à WindowsApplication1.Form2.truc() dans
D:MenuRacourciDeveloppementProg1V2005-4Prog1V2005Form2.vb:ligne 307
à System.Threading.ThreadHelper.ThreadStart_Context(Object state)
à System.Threading.ExecutionContext.runTryCode(Object userData)
à
System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode
code, CleanupCode backoutCode, Object userData)
à System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state)
à System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
à System.Threading.ThreadHelper.ThreadStart()
******************************************************************************

D'apres ce que j'avais compris il faut que je face une seule procedure pour
le meme thread, hors là, ça bloque sur la listview
(LvQueue.Items.Item(0).SubItems.Item(2).Text = "En execution")

Que faire ?

J'ai entendu parler d'une nouvelle fonctionnalité sur la version 2005
(Vb.net) sa s'appelerai "backgroundWorker1_DoWork" il aurait les meme
fonctionnalité que le thread actuel avec des améliorations, mais ça manque
pas mal d'information (en francais) sur le site msdn :)

Des idées ?


@++
Avatar
Julien Bakmezdjian [MS]
Bonsoir,

Oui, effectivement, on a un petit soucis, que j'avais déjà rencontré, mais
vite oublié !
Le second thread n'a pas le droit d'accèder aux contrôles créés par le
premier thread... D'où le message d'erreur... C'est dommage, je pensais
qu'on était près de la fin ! ;)

Bon, je vais essayer de me souvenir comment j'avais réglé ça à l'époque...

Julien

"TroXsA" a écrit dans le message de news:
ddaj0i$p48$
Je doit ne pas etre doué sur le fonctionnement du thread
je croyais avoir tout compris enfait j'ai rien absorbé

Dans mon bouton_Click j'ai mis ma procedure Public Sub EvenBoutonExe
ce qui donne ceci

Private Sub BtnExeQueue_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles BtnExeQueue.Click
Dim t As New Threading.Thread(AddressOf EvenBoutonExe)
t.Start()
End Sub

J'execute le tout ... et ... (Erreur) sur
LvQueue.Items.Item(0).SubItems.Item(2).Text = "En execution"

******************************************************************************
Opération inter-threads non valide : le contrôle 'LvQueue' a fait l'objet
d'un accès à partir d'un thread autre que celui sur lequel il a été créé.
******************************************************************************

L'exception System.InvalidOperationException n'a pas été gérée
Message="Opération inter-threads non valide : le contrôle 'LvQueue' a
fait l'objet d'un accès à partir d'un thread autre que celui sur lequel il
a été créé."
Source="System.Windows.Forms"
StackTrace:
à System.Windows.Forms.Control.get_Handle()
à
System.Windows.Forms.ListView.ListViewNativeItemCollection.DisplayIndexToID(Int32
displayIndex)
à
System.Windows.Forms.ListView.ListViewNativeItemCollection.get_Item(Int32
displayIndex)
à
System.Windows.Forms.ListView.ListViewItemCollection.get_Item(Int32 index)
à WindowsApplication1.Form2.truc() dans
D:MenuRacourciDeveloppementProg1V2005-4Prog1V2005Form2.vb:ligne 307
à System.Threading.ThreadHelper.ThreadStart_Context(Object state)
à System.Threading.ExecutionContext.runTryCode(Object userData)
à
System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode
code, CleanupCode backoutCode, Object userData)
à System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state)
à System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
à System.Threading.ThreadHelper.ThreadStart()
******************************************************************************

D'apres ce que j'avais compris il faut que je face une seule procedure
pour le meme thread, hors là, ça bloque sur la listview
(LvQueue.Items.Item(0).SubItems.Item(2).Text = "En execution")

Que faire ?

J'ai entendu parler d'une nouvelle fonctionnalité sur la version 2005
(Vb.net) sa s'appelerai "backgroundWorker1_DoWork" il aurait les meme
fonctionnalité que le thread actuel avec des améliorations, mais ça manque
pas mal d'information (en francais) sur le site msdn :)

Des idées ?


@++



Avatar
TroXsA
Bonjour Julien B :)

Je vais faire des recherches sur internet voir ce que je trouve, je suis sur
que je suis pas la seule personne qui a rencontré ses problèmes

Si je trouve qu'elle que chose je donnerais la solution qui pourra servir
pour d'autre

Si tu retrouve la solution la solution pense a moi ;)

@+
A bientot
Avatar
Julien Bakmezdjian [MS]
Bonjour,

Il faut en fait utiliser la méthode Invoke des contrôles. Cette méthode
permet d'appeler d'autres méthodes (les vôtres) dans le thread principal, en
passant des paramètres. Grâce à ces paramètres, le thread principal pourra
lui même mettre à jour ses contrôles.

Un exemple est dispo ici :
http://www.codemilitia.com/blogs/tobin.titus/archive/2005/04/10/55.aspx

N'hésitez pas à revenir vers moi,

Cordialement,

Julien Bakmezdjian


"TroXsA" a écrit dans le message de news:
ddcf0a$l9e$
Bonjour Julien B :)

Je vais faire des recherches sur internet voir ce que je trouve, je suis
sur que je suis pas la seule personne qui a rencontré ses problèmes

Si je trouve qu'elle que chose je donnerais la solution qui pourra servir
pour d'autre

Si tu retrouve la solution la solution pense a moi ;)

@+
A bientot



1 2