piter123 (Normal User)
Pro
Messaggi: 145
Iscritto: 21/05/2008
|
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
|
|
nessuno (Normal User)
Guru^2
Messaggi: 6402
Iscritto: 03/01/2010
|
Prima del ritardo aggiungi una linea
Application.DoEvents()
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità. |
|
piter123 (Normal User)
Pro
Messaggi: 145
Iscritto: 21/05/2008
|
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 |
|
nessuno (Normal User)
Guru^2
Messaggi: 6402
Iscritto: 03/01/2010
|
Bisogna capire come è organizzato tutto il programma ... ad esempio, dove sta la Ricezione_ClientSock ?
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità. |
|
piter123 (Normal User)
Pro
Messaggi: 145
Iscritto: 21/05/2008
|
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
|
|
piter123 (Normal User)
Pro
Messaggi: 145
Iscritto: 21/05/2008
|
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
|
|
nessuno (Normal User)
Guru^2
Messaggi: 6402
Iscritto: 03/01/2010
|
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 ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità. |
|
piter123 (Normal User)
Pro
Messaggi: 145
Iscritto: 21/05/2008
|
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 |
|