PDA

View Full Version : [VB.NET 2008] Modificare form da thread separato (Windows CE)


steve.b
16-11-2012, 10:07
Ciao a tutti,
ho un problema riguaro alla modifica di campi (tipo textbox, label, acc) di una form da un altro thread.
Premetto che non sono affatto esperto di Visual Studio 2008 e, purtroppo, nemmeno di VB.NET ma devo usare questi strumenti per scrivere un'applicazione che gira su un dispositivo con Windows CE 5.0.
In questo forum ho già trovato un post a riguardo, "[VB.NET 2005] Modificare una form da un thread separato", ed ho seguito la soluzione proposta.
Tutto funziona se scrivo tutto all'interno della classe del mio form (Form1), ovvero nella Form1 c'è un bottone che avvia un thread che incrementa di 1 una variabile dichiarata all'interno di Form1 e poi chiama una "Sub AggLab()" sempre di Form1 che aggiorna il contenuto di una label (di Form1) con il valore della variabile incrementata:



Imports System.Threading

Public Class Form1
Dim MyNewThread As Thread
Dim tmp As Int32 = 0

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'crea il thread
MyNewThread = New Thread(AddressOf SubDelThread)
MyNewThread.Name = "NuovoThread"
'avvia il thread
MyNewThread.Start()
End Sub


Private Sub SubDelThread()
Do
tmp = tmp + 1
AggLab()
Thread.Sleep(1000)
Loop
End Sub

Private Delegate Sub AggLabDel()
Private Sub AggLab()

If Me.InvokeRequired Then
Me.BeginInvoke(New AggLabDel(AddressOf AggLab))
Return
End If

Label1.Text = tmp.ToString

End Sub

End Class



Però se la funzione eseguita all'interno del thread si trova in un'altra classe/file la cosa non funziona più:


'file Form1.vb

Imports System.Threading

Public Class Form1
Dim MyNewThread As Thread

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'crea il thread
MyNewThread = New Thread(AddressOf MyThread.MyThreadExecute)
MyNewThread.Name = "NuovoThread"
'avvia il thread
MyNewThread.Start()
End Sub

Private Delegate Sub AggiornaLabelDelegate()
Public Sub AggiornaLabel()

If Me.InvokeRequired Then
Me.BeginInvoke(New AggiornaLabelDelegate(AddressOf AggiornaLabel))
Return
End If

Label1.Text = MyThread.iii.ToString

End Sub




'file MyThread.vb

Imports System.Threading

Public Class MyThread
Private Shared miii As Int32 = 0

Public Shared Property iii() As Int32
Get
Return miii
End Get
Set(ByVal value As Int32)
miii = value
End Set
End Property

Public Shared Sub MyThreadExecute()
Do
iii = iii + 1
Form1.AggiornaLabel()
Thread.Sleep(1000)
Loop
End Sub

End Class


quello che verifico con il debug è che in questo caso "Me.InvokeRequired" è sempre false.

Temo di aver commesso qualche errore banale dovuto alla mia inesperienza con vb.net...

Qualcuno può darmi una dritta?

Grazie

steve.b
21-11-2012, 08:40
Ciao, rieccomi qui.
Ho come l'impressione che questo argomento non abbia suscitato grande interesse... ;)
Comunque ho trovato una soluzione postando la domanda in un altro forum e quindi la condivido con voi, magari potrebbe servire a qualcun altro.


'file Form1.vb

Imports System.Threading

Public Class Form1
Dim MyNewThread As Thread

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'create the thread
'MyNewThread = New Thread(AddressOf MyThread.MyThreadExecute)
MyNewThread = New Thread(AddressOf ThreadModule.MyThreadExecute)
MyNewThread.Name = "NuovoThread"
'MyThread.ThatForm = Me
ThreadModule.ThatForm = Me
'start the thread
MyNewThread.Start()
End Sub

Public Sub AggiornaLabel(ByVal What As String)
If InvokeRequired Then
Invoke(New Action(Of String)(AddressOf AggiornaLabel), New Object() {What})
Return
End If

Label1.Text = What
End Sub
End Class



'file ThreadModule.vb
Imports System.Threading

Module ThreadModule
Private miii As Int32 = 0
Public ThatForm As Form1

Public Property iii() As Int32
Get
Return miii
End Get
Set(ByVal value As Int32)
miii = value
End Set
End Property

Public Sub MyThreadExecute()
Do
iii = iii + 1
ThatForm.AggiornaLabel(iii.ToString)
Thread.Sleep(100)
Loop
End Sub
End Module


la cosa funziona anche se al posto di un modulo si usa una classe, ma è meno pulito:


'file MyThread.vb
Imports System.Threading

Public Class MyThread
Private Shared miii As Int32 = 0
Public Shared ThatForm As Form1

Public Shared Property iii() As Int32
Get
Return miii
End Get
Set(ByVal value As Int32)
miii = value
End Set
End Property

Public Shared Sub MyThreadExecute()
Do
iii = iii + 1
ThatForm.AggiornaLabel(iii.ToString)
Thread.Sleep(100)
Loop
End Sub

End Class


ciao