Oula, ça plante mechament quand j'appelle la fonction delais1().
L'interface n'a meme pas le temps de se charger entierement
Oula, ça plante mechament quand j'appelle la fonction delais1().
L'interface n'a meme pas le temps de se charger entierement
Quel message d'erreur obtiens tu ?
Même pas eu le temps d'afficher le message.Par contre, tout a l'heure j'ai redemarer l'ordi et j'ai réesayé avec la methode ThreadPool. Et la j'ai plus de probleme de plantage. ça marche, il est un peu lent pas moment mais ça a l'air de marcher correctement maintenant. C'est bizarre parce que comme tu m'as dis
"C'est parce que tu utilises des méthodes de controles utilisateurs (delai1.Text) dans un thread qui n'a pas crée le controle. C'est interdit dans Windows et ça peux faire freezer l'appli".
Par contre j'ai un mal pas croyable à quitter l'appication, je sais pas pourquoi mais j'ai toujours eu ça des que je fais mes mesures de délai, en particulier les 8 en même temps
C'est quand meme dommage le message que j'ai eu system.outofmemoryexception parce que derriere l'application continuait de tourner parfaitement, sans probleme de lenteur etc...
Mais je reste ouvert a toute solution d'optimisation
Alors plusieurs choses:
Le plantage est aléatoire lorsqu'on utilise les controles utilisateurs dans des threads. Ca peut planter de suite, comme ça peut marcher 1 an avant de planter (ça c'est du vécu), et là tu peux chercher d'où ça vient ... bon courage.
Il faut reussir à bien utiliser BeginInvoke
Sinon pour la fin de l'application, elle doit surement attendre que les threads non system en cours se termine.
Reposte ton code modifié pour voir
OK je t'envoie le code avec les threadPool, mais une seule fonction de delai( histoire de simplifier)
Au passage j'ai 3 version du code, dont une avec les thread que je crée moi meme et qui provoque outofmemory et la version que tu m'a donnée
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 Imports NationalInstruments.DAQmx Imports System.Threading Imports Microsoft.VisualBasic 'Delegate Sub UnDelegateQueTuAsDefiniDlg(ByVal valeur As String, ByVal txt As TextBox) PublicClass Form1 Inherits System.Windows.Forms.Form Private myTask2 As Task Private myTask4 As Task Private myTask5 As Task Private myDigitalReader2 As DigitalSingleChannelReader Private myDigitalReader4 As DigitalSingleChannelReader Private myDigitalReader5 As DigitalSingleChannelReader Private firstEdge As CITwoEdgeSeparationFirstEdge Private secondEdge As CITwoEdgeSeparationSecondEdge Private myTask As Task Private counterInReader As CounterReader ' Private UnDelegateQueTuAsDefini As New UnDelegateQueTuAsDefiniDlg(AddressOf UpdateDelaiUI) PublicSub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) HandlesMyBase.Load blabla pas d'(interet EndSub PrivateSub Timer1_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs) Handles Timer1.Elapsed 'Connection pci dio 96 port 2 Dim readData2() AsBoolean readData2 = myDigitalReader2.ReadSingleSampleMultiLine() Babord.Value = readData2(6) Tribord.Value = readData2(5) blabla gestion de voyants 'Affichage du mode 3d ou 2d If readData4(6) = TrueThen Mode.Text = "3D" ElseIf readData4(6) = FalseThen Mode.Text = "2D" EndIf C1.Value = c1pret.Value C2.Value = Not c2pret.Value C3.Value = c3pret.Value C4.Value = Not c4pret.Value ThreadPool.QueueUserWorkItem(AddressOf delais1) ThreadPool.QueueUserWorkItem(AddressOf delais2) ThreadPool.QueueUserWorkItem(AddressOf delais3) ThreadPool.QueueUserWorkItem(AddressOf delais4) ThreadPool.QueueUserWorkItem(AddressOf delais5) ThreadPool.QueueUserWorkItem(AddressOf delais6) ThreadPool.QueueUserWorkItem(AddressOf delais7) ThreadPool.QueueUserWorkItem(AddressOf delais8) EndSub 'Programmation de fonction, une par délai PublicSub delais1(ByVal state AsObject) Dim max AsDouble = 0.3 Dim min AsDouble = 0.001 Dim valeurdelai1 AsString myTask = New Task myTask.CIChannels.CreateTwoEdgeSeparationChannel("Dev2/ctr2", "", min, _ max, CITwoEdgeSeparationFirstEdge.Rising, CITwoEdgeSeparationSecondEdge.Rising, CITwoEdgeSeparationUnits.Seconds) counterInReader = New CounterReader(myTask.Stream) Dim data AsDouble = counterInReader.ReadSingleSampleDouble() valeurdelai1 = data.ToString delai2.Text = valeurdelai1 EndSub EndClass
Je vais quand même apporter une petite précision quand même sur cette histoire de délai, on sait jamais. Il s'agit d'une mesure de délai entre le front montant d'un signal et le front montant d'un autre signal. IL y a 8 délais en tout. Mais il n'y a que 2 qui se font en même temps, les autres sont en attente, et il n'y a que 2-3 secondes environs chaque fois qu'il doit mesurer 2 delais en même temps. Et ça doit tourner des heures comme ça.
Dans la fonction delai1,
Si tu remplace
delai2.text=valeurdelai1 par
ça donne quoi ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 If InvokeRequired then BeginInvoke(UnDelegateQueTuAsDefini, new Object() {ValeurDelai1, Delai2 }) else DElai2.Text = valeurdelai1 endif
NIDAQmx propose des méthodes asynchrones qui permettent de déclencher un événement quand la mesure est terminée : CounterReader.BeginRead...() et AsyncCallback
C'est plus simple que de créer soi-même un thread pour attendre la réponse d'une méthode synchrone.
Il doit exister une méthode pour terminer les tâches en cours quand on ferme l'application (Task.Dispose ou Discard) C'est toi qui a la doc.
Ceci dit, le problème de mise à jour de l'interface graphique reste le même et le framework permet de le résoudre : Control.BeginInvoke()
J'en profite pour envoyer ma précédente version avec beginInvoke et endInvoke. Pareil, ça marche mais c'est lent. La version la plus rapide etait quand meme la premiere que j'ai postée (mis a part le message d'erreur qui m'obligeait à quitter).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 Imports NationalInstruments.DAQmx Imports System.Threading Imports Microsoft.VisualBasic PublicClass Form1 Inherits System.Windows.Forms.Form Private myTask2 As Task Private myTask4 As Task Private myTask5 As Task Private myDigitalReader2 As DigitalSingleChannelReader Private myDigitalReader4 As DigitalSingleChannelReader Private myDigitalReader5 As DigitalSingleChannelReader Private firstEdge As CITwoEdgeSeparationFirstEdge Private secondEdge As CITwoEdgeSeparationSecondEdge Private myTask As Task Private trigger1 As Task Private counterInReader As CounterReader Private affichage1 AsNew async(AddressOf delais1) Private affichage2 AsNew async1(AddressOf delais2) Private affichage3 AsNew async2(AddressOf delais3) Private affichage4 AsNew async3(AddressOf delais4) Private affichage5 AsNew async4(AddressOf delais5) Private affichage6 AsNew async5(AddressOf delais6) Private affichage7 AsNew async6(AddressOf delais7) Private affichage8 AsNew async7(AddressOf delais8) PrivateSub Timer1_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs) Handles Timer1.Elapsed 'Connection pci dio 96 port 2 'crée un délégué et affiche le delai de manière asynchrone affichage1.BeginInvoke(AddressOf display1, Nothing) affichage2.BeginInvoke(AddressOf display2, Nothing) affichage3.BeginInvoke(AddressOf display3, Nothing) affichage4.BeginInvoke(AddressOf display4, Nothing) affichage5.BeginInvoke(AddressOf display5, Nothing) affichage6.BeginInvoke(AddressOf display6, Nothing) affichage7.BeginInvoke(AddressOf display7, Nothing) affichage8.BeginInvoke(AddressOf display8, Nothing) EndSub DelegateFunction async() DelegateFunction async1() DelegateFunction async2() DelegateFunction async3() DelegateFunction async4() DelegateFunction async5() DelegateFunction async6() DelegateFunction async7() 'Programmation de fonction, une par délai, 8 en tout PublicFunction delais1() Dim max AsDouble = 0.3 Dim min AsDouble = 0.001 Dim valeurdelai AsString myTask = New Task Dim channel AsString myTask.CIChannels.CreateTwoEdgeSeparationChannel("Dev2/ctr0", "", min, _ max, CITwoEdgeSeparationFirstEdge.Rising, CITwoEdgeSeparationSecondEdge.Rising, CITwoEdgeSeparationUnits.Seconds) counterInReader = New CounterReader(myTask.Stream) Dim data AsDouble = counterInReader.ReadSingleSampleDouble() valeurdelai = data.ToString Return valeurdelai EndFunction 'Programmation de fonction pour afficher les délais de manière asynchrone, 8 en tout. PublicSub display1(ByVal ia1 As IAsyncResult) Delai1.Text = affichage1.EndInvoke(ia1) EndSub
Je ne connais pas cette librairy mais absolument d'accord avec NicolaG.Envoyé par NicolasG
Sinon pour ton dernier code, tu t'en mêles les pinceaux je pense.
Essaye ceci
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 Imports NationalInstruments.DAQmx Imports System.Threading Imports Microsoft.VisualBasic Delegate Sub UnDelegateQueTuAsDefiniDlg(ByVal valeur As String, ByVal txt As TextBox) PublicClass Form1 Inherits System.Windows.Forms.Form Private myTask2 As Task Private myTask4 As Task Private myTask5 As Task Private myDigitalReader2 As DigitalSingleChannelReader Private myDigitalReader4 As DigitalSingleChannelReader Private myDigitalReader5 As DigitalSingleChannelReader Private firstEdge As CITwoEdgeSeparationFirstEdge Private secondEdge As CITwoEdgeSeparationSecondEdge Private myTask As Task Private counterInReader As CounterReader Private UnDelegateQueTuAsDefini As New UnDelegateQueTuAsDefiniDlg(AddressOf UpdateDelaiUI) PublicSub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) HandlesMyBase.Load blabla pas d'(interet EndSub PrivateSub Timer1_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs) Handles Timer1.Elapsed 'Connection pci dio 96 port 2 Dim readData2() AsBoolean readData2 = myDigitalReader2.ReadSingleSampleMultiLine() Babord.Value = readData2(6) Tribord.Value = readData2(5) blabla gestion de voyants 'Affichage du mode 3d ou 2d If readData4(6) = TrueThen Mode.Text = "3D" ElseIf readData4(6) = FalseThen Mode.Text = "2D" EndIf C1.Value = c1pret.Value C2.Value = Not c2pret.Value C3.Value = c3pret.Value C4.Value = Not c4pret.Value ThreadPool.QueueUserWorkItem(AddressOf delais1) ThreadPool.QueueUserWorkItem(AddressOf delais2) ThreadPool.QueueUserWorkItem(AddressOf delais3) ThreadPool.QueueUserWorkItem(AddressOf delais4) ThreadPool.QueueUserWorkItem(AddressOf delais5) ThreadPool.QueueUserWorkItem(AddressOf delais6) ThreadPool.QueueUserWorkItem(AddressOf delais7) ThreadPool.QueueUserWorkItem(AddressOf delais8) EndSub 'Programmation de fonction, une par délai PublicSub delais1(ByVal state AsObject) Dim max AsDouble = 0.3 Dim min AsDouble = 0.001 Dim valeurdelai1 AsString myTask = New Task myTask.CIChannels.CreateTwoEdgeSeparationChannel("Dev2/ctr2", "", min, _ max, CITwoEdgeSeparationFirstEdge.Rising, CITwoEdgeSeparationSecondEdge.Rising, CITwoEdgeSeparationUnits.Seconds) counterInReader = New CounterReader(myTask.Stream) Dim data AsDouble = counterInReader.ReadSingleSampleDouble() valeurdelai1 = data.ToString If InvokeRequired then BeginInvoke(UnDelegateQueTuAsDefini, new Object() {ValeurDelai1, Delai2 }) else Delai2.Text = valeurdelai1 endif EndSub Sub UpdateDelaiUI(valeur as String, txt As TextBox ) txt.Text = valeur End Sub EndClass
Partager