Newsgroup: it.comp.lang.visual-basic
Titolo: [?][SOCKET] Interferenze con le istruzioni DoEvents e Refresh di una label

Salve a tutti.
Sto realizzando un programma per scaricare da un server news l'elenco dei
gruppi.
Questo è il codice.
News è una variabile di tipo DataBase, il database dove vado a mettere
l'elenco.
Account è una variabile di tipo Recordset, la uso per leggere il nome del
server a cui collegarsi.
Socket è il nome di un controllo Winsock.
Stato è una variabile enum che contiene lo stato del programma, inizialmente
= Disconnected.
NextStato è una variabile enum che contiene lo stato futuro del programma,
inizialmente = Disconnected.
Ricevuti è una variabile che contiene il numero di gruppi scaricati.
Private Sub cmdReimposta_Click()
   News.Execute "Elimina gruppi"  'query che cancella l'elenco dei gruppi
   Account.MoveFirst
   NextStato = List
   Socket.Connect CStr(Account!Server), 119
End Sub
Private Sub Socket_DataArrival(ByVal bytesTotal As Long)
   Static S As String
   Dim C As String * 1
   Dim I As Long
   For I = 1 To bytesTotal
      Socket.GetData C, vbString, 1
      S = S + C
      If Right(S, 2) = vbCrLf Then
         StringArrival (Left(S, Len(S) - 2))
         S = ""
      End If
   Next I
End Sub
Private Sub StringArrival(ByVal S As String)
   If Stato <= Connected Then
      StatusArrival Left(S, 3), Mid(S, 5)
   Else
      If Left(S, 1) = ".." Then S = Mid(S, 2)
      Select Case Stato
         Case List: AggiungiGruppo S, False
         Case NewList: AggiungiGruppo S, True
      End Select
   End If
End Sub
Private Sub StatusArrival(ByVal Cod As String, ByVal Status As String)
   Debug.Print Cod & " " & Status
   Select Case Cod
      Case "200", "201" 'Connesso
         Stato = Connected
         Select Case NextStato
            Case List: Socket.SendData "list" & vbCrLf
         End Select
         Ricevuti = 0
      Case "205" 'Fine lavoro
         Stato = Disconnected
         Socket.Close
      Case "215": Stato = List 'Inizio trasmissione lista
      Case "400", "500", "501", "502", "503" 'Errore
        Stato = Disconnected
        Socket.Close
   End Select
End Sub
Private Sub AggiungiGruppo(ByVal S As String, ByVal Nuovo As Boolean)
   Ricevuti = Ricevuti + 1
   If S = "." Then
      Stato = Connected
      If Aggiornamento.RecordCount > 0 Then Aggiornamento.Edit Else
Aggiornamento.AddNew
      Aggiornamento!Data = Now
      Aggiornamento.Update
      lblNum = ""
      tbsGruppi_Click
      Socket.SendData "quit" & vbCrLf
   Else
      Gruppi.AddNew
      If Ricevuti Mod 100 = 0 Then
         lblNum = "Gruppi scaricati: " & Ricevuti
         lblNum.Refresh
      End If
      Gruppi!Nome = Left(S, InStr(S, " ") - 1)
      S = Mid(S, InStr(S, " ") + 1)
      Gruppi!Ultimo = CLng(Left(S, InStr(S, " ") - 1))
      S = Mid(S, InStr(S, " ") + 1)
      Gruppi!Primo = CLng(Left(S, InStr(S, " ") - 1))
      S = Mid(S, InStr(S, " ") + 1)
      Gruppi!Invio = (S = "y")
      Gruppi!Sottoscritto = False
      Gruppi!Nuovo = Nuovo
      Gruppi.Update
   End If
End Sub
Private Sub Socket_Error(ByVal Number As Integer, Description As String,
ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal
HelpContext As Long, CancelDisplay As Boolean)
   Debug.Print Number; Description
   Socket.Close
End Sub
Nella sub AggiungiGruppo si può notare che ogni cento gruppi scaricati
aggiorno una label, e quì sta il problema.
Il problema è che la lettura dell'elenco è lenta, si vede che il modem
lavora per alcuni secondi, poi per altri rimane fermo, poi riparte e così
via, con una lunga sequenza di tempi morti.
Vi chiederete, cosa centra la lentezza nel download con l'aggiornamento
dell'etichetta?
Il fatto è che se sostituisco l'istruzione lblNum.Refresh con un DoEvents
allora l'esecuzione diventa velocissima!!! (si fa per dire, comunque
spariscono i tempi morti, la velocità è simile a quella con cui scarica OE).
Allora vi chiedo, come può un refresh di una label a rallentare così
l'operazione? Come faccio a velocizzare il download?
Mi direte: togli il refresh e metti il DoEvents! E no, mi spiace, non vale!
Infatti c'è un altro problema usando il DoEventes. Dopo aver scaricato circa
9000 gruppi, la DoEvents mi provoca un errore di overflow nello stack.
--
Samuele Battarra
mail server: 
libero.it
, account: battarsa

 End Sub
Io punterei il dito anche su questa routine. In pratica ad ogni 
arrivo di dati il ciclo for aggiunge UN solo carattere alla stringa, 
ciclando per tutta la lunghezza del buffer...  Anche io ho realizzato
un lettore di news (
http://socket2000.8m.com
) e la maggior difficoltà
incontrata era appunto la velocità della routine di 'smistamento' 
dati, che se non era perfetta mi perdeva dei dati per strada, 
rallentando il tutto. Ho trovato una ocx (freeware) che si comportava
in maniera egregia, e che permette di scaricare tutto il buffer di 
arrivo in un colpo, con ovvii miglioramenti. Il fatto che il doevents
ti causi un errore di overflow nello stack potrebbe dipendere dal 
fatto che (ma mi potrei sbagliare) arrivino nuovi dati mentre ancora 
la routine sta ciclando il for dei dati precedenti, in questo modo lo
stack si riempie perchè la stessa routine viene richiamata dai nuovi 
dati mentre sono ancora processati quelli vecchi, e via di seguito. 
Se ti può interessare la ocx è socket wrench su 
www.catalyst.com
-- 
News2000 1.5ß Version 
http://socket2000.8m.com

 dati mentre sono ancora processati quelli vecchi, e via di seguito.
Questo non mi convince molto. Se fosse questo il motivo, passando ad una
macchina più veloce dovrebbe ritardare il momento in cui dà l'errore, ma
così non è.


Dopo aver sostiutito la sub sopra fila che è una meraviglia. Inoltre,
nonostante non ci siano DoEvents, l'applicazione non si blocca. Forse era
questo il problema, le mettevo quando invece non co volevano.

 questo il problema, le mettevo quando invece non co volevano.
Meglio cosě.
