Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - VBNET Problema con socket e form Mdi
Forum - C# / VB.NET - VBNET Problema con socket e form Mdi

Avatar
piter123 (Normal User)
Pro


Messaggi: 136
Iscritto: 21/05/2008

Segnala al moderatore
Postato alle 17:52
Martedì, 04/12/2012
salve, ho una form Mdi padre con una toolstrip con all'interno una toolstriplabel ,
ho un modulo dove ho inserito le routine per la connessione tramite socket ad
un server remoto. Funziona tutto.
Il problema stà nell'aggiornare la toolstriplabel che non mi si aggiorna con il dato
che ricevo in tempo reale ogni secondo da parte del server remoto.
Se invece copio tutte le routine del modulo direttamente sulla form Mdi si aggirona.
Perchè ???

Public Sub Ricezione_ClientSock()
        Dim Campo()
        Do While True
            If ClientSocket.Connected = True Then
                If ClientSocket.Available <> 0 Then

                    'RICEVE DATO
                    ServerStream = ClientSocket.GetStream()
                    Dim buffSize As Integer
                    Dim inStream(10024) As Byte
                    buffSize = ClientSocket.ReceiveBufferSize
                    ServerStream.Read(inStream, 0, buffSize)
                    Dim Dato As String = System.Text.Encoding.ASCII.GetString(inStream)

                    'FILTRA DATO
                    Select Case Dato.Substring(0, 6)

                        Case "COMM12"
                            'CONFERMA AUTENTICAZIONE RIUSCITA
                            Campo = Split(Dato, ";")
                            FMdi.Text = Campo(1) & " Connesso"

                        
                        Case "COMM31"
                            'RICEVE DATA E ORA DAL SERVER
                            Campo = Split(Dato, ";")
                            FMdi.TsLblTime.Text = Campo(1)                     'toolstriplabel

                    End Select
                End If
            End If
            Ritardo(100)
        Loop

    End Sub

PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5460
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 18:31
Martedì, 04/12/2012
Prima del ritardo aggiungi una linea

Application.DoEvents()


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
piter123 (Normal User)
Pro


Messaggi: 136
Iscritto: 21/05/2008

Segnala al moderatore
Postato alle 18:38
Martedì, 04/12/2012
purtroppo niente da fare, inoltre il doevent l'ho già inserito nella routine di ritardo.
A debug passo passo esegue la riga  FMdi.TsLblTime.Text = Campo(1)  
e campo(1) che ovviamente è pieno, ma poi non visualizza. Bhooo non
capisco


Public Sub Ritardo(ByVal TIME_RITARDO As Integer)
        'IL VALORE RITARDO E' IN MILLISECONDI 1 SECONDO = 1000
        Dim StartTime As Date = Now
        Do
            Application.DoEvents()
        Loop Until (Now - StartTime).TotalMilliseconds > TIME_RITARDO
    End Sub

Ultima modifica effettuata da piter123 il 04/12/2012 alle 18:39
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5460
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 19:14
Martedì, 04/12/2012
Bisogna capire come è organizzato tutto il programma ... ad esempio, dove sta la Ricezione_ClientSock ?


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
piter123 (Normal User)
Pro


Messaggi: 136
Iscritto: 21/05/2008

Segnala al moderatore
Postato alle 7:53
Mercoledì, 05/12/2012
la gestione del socket come dicevo si trova in un modulo.
La label FMdi.TsLblTime si trova sulla form mdi padre.
Potrebbe dipendere dalla riga :
Dim ctThread As Threading.Thread = New Threading.Thread(AddressOf Ricezione_ClientSock)
ctThread.Start()

che apre un nuovo thread ??



Option Explicit On
Imports System.Net.Sockets
Imports System.Text

Module M_Socket
    'DICHIARAZIONE OGGETTI SOCKET
    Dim ClientSocket As TcpClient 'Variabile client
    Dim ServerStream As NetworkStream 'Variabile flusso di dati client-server

    Public Sub Connessione_ClientSock()
        Try
            ClientSocket = New TcpClient
            ClientSocket.Connect(IPServer, PortaServerSock)
            Call Ritardo(100)
            Call Richiesta_autorizzazione()
        Catch ex As Exception
            ClientSocket.Close()
            MessageBox.Show("errore nella connessione sock con il server")
        End Try
    End Sub

    Public Sub Richiesta_autorizzazione()
        'DICHIARAZIONE VARIABILI
        Dim Stringa As String
        'MANDA DATI AUTENTICAZIONE AL SERVER
        If ClientSocket.Connected Then
            Stringa = "COMM11" & ";" & UserSock & ";" & PassSock & ";" & ReleasePrg & ";"
            serverStream = ClientSocket.GetStream()
            Dim outStream As Byte() = _
            System.Text.Encoding.ASCII.GetBytes(Stringa)
            serverStream.Write(outStream, 0, outStream.Length)
            serverStream.Flush()
            'REINDIRIZZA LE RISPOSTE DAL SERVER ALLA ROUTINE Ricezione_ClientSock
            Dim ctThread As Threading.Thread = New Threading.Thread(AddressOf Ricezione_ClientSock)
            ctThread.Start()
        Else
            Call Chiude_Sock()
        End If
    End Sub

    Public Sub Chiude_Sock()
        Dim Stringa As String
        If ClientSocket.Connected Then
            Stringa = "COMM18" & ";"
            ServerStream = ClientSocket.GetStream()
            Dim outStream As Byte() = _
            System.Text.Encoding.ASCII.GetBytes(Stringa)
            ServerStream.Write(outStream, 0, outStream.Length)
            ServerStream.Flush()
        End If
        Call Ritardo(200)
        ClientSocket.Close()
    End Sub

    Public Sub Ricezione_ClientSock()
        Dim Campo()
        Do While True
            If ClientSocket.Connected = True Then
                If ClientSocket.Available <> 0 Then

                    'RICEVE DATO
                    ServerStream = ClientSocket.GetStream()
                    Dim buffSize As Integer
                    Dim inStream(10024) As Byte
                    buffSize = ClientSocket.ReceiveBufferSize
                    ServerStream.Read(inStream, 0, buffSize)
                    Dim Dato As String = System.Text.Encoding.ASCII.GetString(inStream)

                    'FILTRA DATO
                    Select Case Dato.Substring(0, 6)

                        Case "COMM12"
                            'CONFERMA AUTENTICAZIONE RIUSCITA
                            Campo = Split(Dato, ";")
                            FMdi.Text = Campo(1) & " Connesso"

                        Case "COMM31"
                            'RICEVE DATA E ORA DAL SERVER
                            Campo = Split(Dato, ";")
                            FMdi.TsLblTime.Text = Campo(1)
            
                    End Select
                End If
            End If
            Application.DoEvents()
            Ritardo(100)
        Loop

    End Sub

PM Quote
Avatar
piter123 (Normal User)
Pro


Messaggi: 136
Iscritto: 21/05/2008

Segnala al moderatore
Postato alle 9:43
Mercoledì, 05/12/2012
penso proprio dipenda dall'apertura del nuovo thread perchè se lo sostituisco
con un timer per il controllo di ClientSocket.Available <> 0  aggiorna la
FMdi.TsLblTime.Text in maniera corretta.
Ora la domanda è perchè aprendo un nuovo thread mi succede che non aggiorna
la FMdi.TsLblTime.Text ?

Grazie

PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5460
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 16:41
Mercoledì, 05/12/2012
Ecco ... appunto ... se avessi detto che lavoravi con un thread diverso allora avremmo capito prima.

Per aggiornare un controllo da un thread diverso da quello che l'ha creato devi usare del codice opportuno.

Leggi questo

http://msdn.microsoft.com/en-us/library/ms171728.aspx


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
piter123 (Normal User)
Pro


Messaggi: 136
Iscritto: 21/05/2008

Segnala al moderatore
Postato alle 9:28
Martedì, 11/12/2012
ok, giusto hai ragione, ma non sapevo dipendesse da quello, perdona la mia ignoranza.
Da quello che ho capito se creo un nuovo thread non posso eseguire azioni dirette su oggetti
creati da un thread diverso, posso aggirare l'ostacolo con il metodo delegate

Private Delegate Sub DelegateAddText(ByVal str As String)
Private DelegateMdiText As New DelegateAddText(AddressOf FMdiText)

Private Sub FMdiText(ByVal Stringa As String)      'Delegate causa SockThread
        FMdi.Text = Stringa & " CONNESSO"
    End Sub

FMdi.Invoke(DelegateMdiText, "prova")


Cercando un pò su internet ho provato però pure a cambiare l'attributo in sta del thread
ctThread.SetApartmentState(Threading.ApartmentState.STA)

e con quest'ultimo non serve più il Delegate ma posso richiamare direttamente l'oggetto.

Non capisco bene però la differenza tra STA e MTA, Se creo un Thread con attributo STA, creo un thread indipendente dal principale o sostituisco il nuovo thread al thread princiapale?



Ultima modifica effettuata da piter123 il 11/12/2012 alle 10:39
PM Quote