Bonjour,
Mon problème concerne la fluidité d'affichage de mon application.
J'ai une application "Winform" contenant une Form (FormMain) qui est chargée d'instancier et d'afficher simultanément 2 form :
- "FormFullscreen" (affichée en Fullscreen) contient un Webbrowser affichant une page html composée d'une animation Flash (appelons-la "FlashGourmand" ) relativement gourmande en ressource.
- "FormBandeau" (avec TopMost=True et Height=200 px) contient un Webbrower affichant une page html composée d'une animation Flash, un peu moins gourmande que l'autre (appelons-la "FlashBandeau").
Lorsque j'exécute mon application, cela se traduit par un ralentissement, voir un arrêt, de l'animation dans "FlashBandeau" parce que "FlashGourmand" utilise les ressources.
Précision importante, si j'exécute simultanément 2 fois mon appli, la 1er fois avec "FormFullscreen", la seconde avec "FlashBandeau", l'affichage est ok, et aucun ralentissement remarquée, ma machine est donc assez puissante pour l'application... (pour précision, je n'ai pas nécessairement besoin d'utiliser cette appli sur une machine peu puissante. Il est également envisageable que la machine disposera d'une processeur multi-core.)
Après moult recherche, j'ai créé des Thread avec STA, Invoke etc. j'ai également utilisé un backgroundworker qui est sensé permettre de ne pas bloquer lors de l'evenement "navigate" ...
Bref, pour résumé, pour essayer de palier le problème, j'ai essayé plusieurs solutions :
- Solution 1 : Création de 2 Threads dans la Form de lancement, 1 Thread pour créer et afficher FormFullscreen et 1 Thread pour créer et afficher FormBandeau -> cela n'a rien changé
- Solution 2 : Solution 1 + ajout d'un backgroundWorker contenant l'instance du navigateur dans chaque Form -> cela n'a rien changé
- Solution 3 : Solution 2 + masque d'affinité sur le Thread pour lancer un Thread sur le 1er Core et l'autre sur le 2eme Core. -> là je bloque j'y arrive pas , j'ai tenté le coup avec la propriété "ProcessorAffinity" des objets "ProcessThread" mais ca ne change rien...
Pour la solution 3, j'ai trouvé quelques liens en VB6 que je n'arrive pas à exploiter, j'ai également trouvé quelques infos http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx en C (???), il semblerait qu'il faille utiliser "SetThreadAffinityMask " mais je n'y arrive pas
Dans un premier temps, j'aimerais avoir confirmation qu'il est possible de répartir sur plusieurs Threads la charge d'affichage (typiquement les animations Flash) et si oui, quelqu'un dispose t'il d'un exemple en VB.NET ?
Je termine en précisant qu'il n'est pas possible d'optimiser "FlashGourmand" et que la solution de répartir les Thread sur les cores me parait la meilleure, même si malheureusement "FlashGourmand" n'utilisant qu'un seule core, il risque d'y avoir un core utilisé à 100% et un autre sous-exploitée à 5% (comme je l'ai dit FlashBandeau n'est pas très gourmand).
Ci-dessous, vous trouverez le code pour la solution 2 :
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
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166 Imports System.Threading Public Class FormMain Private Sub FormMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim myThread1 As New ThreadForm() Dim monThread1 As New Thread(AddressOf myThread1.affiche) monThread1.IsBackground = True monThread1.SetApartmentState(ApartmentState.STA) monThread1.Start() monThread1.Priority = ThreadPriority.Highest Dim myThread2 As New ThreadForm() Dim monThread2 As New Thread(AddressOf myThread2.defile) monThread2.IsBackground = False monThread2.SetApartmentState(ApartmentState.STA) monThread2.Start() monThread2.Priority = ThreadPriority.Highest End Sub Private Delegate Sub FormInvokeHandler() Private Delegate Sub FormInvokeHandler2() Class ThreadForm Public monNavigateur As WebBrowser Public m_form As FormPerso Public Sub New() m_form = New FormPerso m_form.Show() End Sub Public Sub affiche() Try If m_form.InvokeRequired Then m_form.Invoke(New FormInvokeHandler(AddressOf m_form.affiche)) Else affiche() End If Catch ex As Exception MessageBox.Show("affiche " & ex.Message.ToString) End Try End Sub Public Sub defile() Try If m_form.InvokeRequired Then m_form.Invoke(New FormInvokeHandler2(AddressOf m_form.defileNav)) Else defile() End If Catch ex As Exception MessageBox.Show("defile " & ex.Message.ToString) End Try End Sub End Class Class FormPerso Inherits Form Public WithEvents m_monNavigateur As WebBrowser Public WithEvents BackgroundWorker1 As System.ComponentModel.BackgroundWorker Public WithEvents BackgroundWorker2 As System.ComponentModel.BackgroundWorker Public Sub New() End Sub ''' <summary> ''' Affiche FlashGourmand ''' </summary> ''' <remarks></remarks> Public Sub affiche() Try Me.TopMost = False m_monNavigateur = New WebBrowser Me.Controls.Add(m_monNavigateur) Me.WindowState = FormWindowState.Maximized BackgroundWorker1 = New System.ComponentModel.BackgroundWorker BackgroundWorker1.RunWorkerAsync(m_monNavigateur) Catch ex As Exception MessageBox.Show("affiche " & ex.Message.ToString) End Try End Sub ''' <summary> ''' Affichage FlashBandeau ''' </summary> ''' <remarks></remarks> Public Sub defileNav() Try Me.Width = My.Computer.Screen.Bounds.Width Me.Left = 0 Me.Height = 200 Me.Top = My.Computer.Screen.Bounds.Height - Me.Height Me.TopMost = True Application.DoEvents() m_monNavigateur = New WebBrowser Me.Controls.Add(m_monNavigateur) BackgroundWorker2 = New System.ComponentModel.BackgroundWorker BackgroundWorker2.RunWorkerAsync(m_monNavigateur) Catch ex As Exception MessageBox.Show("defileNav " & ex.Message.ToString) End Try End Sub Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork Try If m_monNavigateur.InvokeRequired Then m_monNavigateur.Invoke(New FormInvokeHandler(AddressOf afficheT)) Else afficheT() End If Catch ex As Exception MessageBox.Show("BackgroundWorker1_DoWork " & ex.Message.ToString) End Try End Sub Private Sub BackgroundWorker2_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker2.DoWork Try If m_monNavigateur.InvokeRequired Then m_monNavigateur.Invoke(New FormInvokeHandler(AddressOf defileT)) Else defileT() End If Catch ex As Exception MessageBox.Show("BackgroundWorker2_DoWork " & ex.Message.ToString) End Try End Sub Public Sub afficheT() Try m_monNavigateur.Dock = DockStyle.Fill m_monNavigateur.Visible = True m_monNavigateur.Navigate("C:/flashGourmand.html") Catch ex As Exception MessageBox.Show("afficheT " & ex.Message.ToString) End Try End Sub Public Sub defileT() Try m_monNavigateur.Dock = DockStyle.Fill m_monNavigateur.Visible = True m_monNavigateur.Navigate("C:/flashBandeau.html") Catch ex As Exception MessageBox.Show("defileMoi " & ex.Message.ToString) End Try End Sub End Class End Class
Merci d'avance à tout ceux qui se pencheront sur mon problème...
Partager