Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - Operazione cross-thread non valida
Forum - C# / VB.NET - Operazione cross-thread non valida

Avatar
orma674 (Normal User)
Pro


Messaggi: 66
Iscritto: 02/06/2008

Segnala al moderatore
Postato alle 19:41
Lunedì, 29/08/2016
Ciao a tutti.
Cerco aiuto per superare l'errore in oggetto, premetto senza disattivare il controllo da codice.

Vi riporto il codice che ho scritto per testare, se qualcuno mi da una mano a renderlo funzionale.

Imports System.Threading.Thread

Public Class Form1
    Dim WithEvents xx As New test

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        'CheckForIllegalCrossThreadCalls = False
    End Sub

    Private Sub xx_testEvento(sender As Object, e As newEvento) Handles xx.testEvento
        Me.Text = e.data
    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        xx.onTest()
    End Sub
End Class

Public Class newEvento
    Inherits EventArgs

    Public data
End Class

Public Class test
    Dim eee As New newEvento

    Public Delegate Sub testDelegate(ByVal sender As Object, e As newEvento)
    Public Event testEvento(ByVal sender As Object, e As newEvento)
    Public ff As New Threading.Thread(AddressOf onThread)

    Public Sub onTest()
        ff.Start()
    End Sub

    Sub onThread()

        Do

            onXXX()
        Loop
    End Sub

    Protected Overridable Sub onXXX()
        eee.data = TimeOfDay.ToString
        RaiseEvent testEvento(Me, eee)
    End Sub
End Class

Ringrazio tutti anticipatamente della collaborazione.
Marcello

PM Quote
Avatar
GN (Member)
Guru


Messaggi: 772
Iscritto: 30/04/2011

Segnala al moderatore
Postato alle 10:57
Martedì, 30/08/2016
Per fare in modo che del codice venga eseguito sul thread della GUI puoi servirti del metodo Invoke. Qui c'è un esempio: https://msdn.microsoft.com/en-us/library/ms171728(v=vs.110) ...
Quindi penso potresti risolvere modificando xx_testEvento in questo modo (non l'ho testato):
Codice sorgente - presumibilmente VB.NET

  1. Delegate Sub SetTextCallback(sender As Object, e As newEvento)
  2.  
  3.     Private Sub xx_testEvento(sender As Object, e As newEvento) Handles xx.testEvento
  4.       If Me.InvokeRequired Then
  5.          Me.Invoke(New SetTextCallback(AddressOf xx_testEvento), sender, e)
  6.       Else
  7.          Me.Text = e.data
  8.       End If
  9.     End Sub


In pratica leggendo la proprietà InvokeRequired il metodo "capisce" se sta girando sul thread secondario (InvokeRequired == true), e quindi utilizza Invoke() per rieseguire se stesso ma sul thread della GUI; questa volta InvokeRequired == false e quindi esegue la modifica effettiva del testo.

PM Quote
Avatar
orma674 (Normal User)
Pro


Messaggi: 66
Iscritto: 02/06/2008

Segnala al moderatore
Postato alle 18:56
Martedì, 30/08/2016
Grazie.
Il codice funziona perfettamente ma io vorrei realizzare una classe chiusa dove può essere utilizzato direttamente la valorizzazione dell'evento senza scrivere codice di delegate da parte dell'utilizzatore.

PM Quote
Avatar
GN (Member)
Guru


Messaggi: 772
Iscritto: 30/04/2011

Segnala al moderatore
Postato alle 10:54
Mercoledì, 31/08/2016
La situazione si complica un pochino perchè come vedi per fare l'invoke hai bisogno di fare riferimento ad un controllo (nel codice di prima era Me che fa riferimento all'istanza di Form1). Forse può interessarti questo articolo: http://www.codeproject.com/Articles/21168/Raising-Events-f ....

PM Quote