Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it L'avatar di mvent
    Registrato dal
    Jun 2002
    Messaggi
    230

    [vb6] sbloccare form dopo routine pesante.

    Salve a todos!

    ho un programmino che funziona perfettamente tranne che per una cosa che non dipende effettivamente dal mio programmino...
    in questo programma eseguo una routine un po' pesante che dura circa un'ora. a volte, al termine della routine, la form rimane bloccata. nel senso che se clicco su un pulsante della form o una casella di testo, sento l'odioso suono di windows e non riesco ad entrare nelle text box oppure a pigiare effettivamente i pulsanti. questo non deriva dal fatto che il programma si sia bloccato in qualche punto: questo lo so per certo perché nella form ho messo un controllo label che mi indica in ogni secondo in quale punto del codice si trova il programma.
    mi visualizza che il programma è uscito dalla routine e non sta eseguendo nulla, ma la form rimane impallata.
    ho provato con varie tattiche, impostando alla fine della routine alcune istruzioni per "svegliare" la form:
    - ho provato ha cambiare il valore della proprietù visible da true a false a true
    - ho provato ad annullare ed eliminare l'oggetto che nella form eseguiva il maggior numero di operazioni (un webbrowser)
    - ho provato con il me.show

    ma non funzia.
    a volte rimane incriccata e l'unico modo per uscire è chiudere il processo dalla gestione processi di winzozz.
    come si può fare per svegliareriattivare sta form?!?!?

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Intanto il sistema non si chiama "winzozz" ma Windows. E' importante dato che tanti ci lavorano e ci vivono.

    Per il problema, mi sembra che basterebbe una

    DoEvents

    all'interno del ciclo piu' pesante che viene eseguito nella tua routine.

    Il consiglio e' anche di rivedere la routine e migliorarla. Molto probabilmente, puoi effettuare lo stesso lavoro in maniera piu' veloce se ottimizzi il codice.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it L'avatar di mvent
    Registrato dal
    Jun 2002
    Messaggi
    230
    il codice è super-ottimizzato, è un mese che lo miglioro e lo adatto al lavoro che deve svolgere.
    il doevents che effetto potrebbe avere se la form non sta eseguendo alcunché, perché ha finito di elaborare l'intera routine?

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Originariamente inviato da mvent
    il codice è super-ottimizzato, è un mese che lo miglioro e lo adatto al lavoro che deve svolgere.
    il doevents che effetto potrebbe avere se la form non sta eseguendo alcunché, perché ha finito di elaborare l'intera routine?
    Se il problema si verifica durante l'elaborazione, allora usa il DoEvents. Se il programma non risponde e sei sicuro che la routine sia terminata, è evidente che, se non mostri il codice non si puo' mai dare nessuna risposta sensata.

    Usi delle API?

    Il blocco si verifica solo dopo l'uso di questa routine?

    Come mai ci sta delle "ore"?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Utente di HTML.it L'avatar di mvent
    Registrato dal
    Jun 2002
    Messaggi
    230
    io la posterei anche ma è piuttosto lunga...e coinvolge anche altre sub-routine (una decina).
    intanto posso dirti che sono arci-sicuro che la routine sia terminata e il programma non sta eseguendo nulla.
    uso una ventina di API...
    e posso anche dirti che non è un problema che il programma assorbe troppa ram, perché a volte la form rimane bloccata quando il processo ha assorbito circa 30 MB di ram e a volte invece quando ne ha assorbita 200 MB non si blocca. e viceversa.
    il programma è una form con caselle di testo, label e pulsanti, e un oggetto webbrowser.
    è un programma che mi fa delle ricerche nei siti web, quindi lo tengo accesso da circa un'ora a 5-6 ore (per questo può arrivare ad assorbire 200 MB di ram)...
    mano a mano che gira i siti web aggiorna il contenuto di alcune label con i risultati che mi interessano della ricerca.

    ogni tanto elimino e annullo (=nothing) l'oggetto webbrowser e lo ricreo, tutto da codice.
    ho provato anche a eliminare l'oggetto webbrowser quando è finita la routine, ma il form può lo stesso rimanere impallato.
    ovviamente nel codice setto uguale a nothing tutte le variabili oggetto che uso, quando non le uso più...
    a te non è mai capitato?

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Originariamente inviato da mvent
    io la posterei anche ma è piuttosto lunga...e coinvolge anche altre sub-routine (una decina).
    intanto posso dirti che sono arci-sicuro che la routine sia terminata e il programma non sta eseguendo nulla.
    Ma il problema e' legato a questa routine o no ?

    Avviene solo dopo la sua esecuzione o anche in altri casi?

    uso una ventina di API...
    Bisogna anche vedere se le usi bene ...

    a te non è mai capitato?
    No. O almeno, c'era un motivo ben preciso, nel codice che era in esecuzione.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    Utente di HTML.it L'avatar di mvent
    Registrato dal
    Jun 2002
    Messaggi
    230
    Originariamente inviato da oregon
    Ma il problema e' legato a questa routine o no ?

    Avviene solo dopo la sua esecuzione o anche in altri casi?
    scusa oregon sono stato impreciso.
    il problema avviene durante la routine: la form si impalla (nel senso che non ci posso cliccare, ma il contenuto delle label continua ad aggiornarsi eccetera), ma il programma continua a funzionare.
    poi il programma finisce di fare la routine e la form rimane bloccata.

    diciamo che capita il 50% delle volte.


    Originariamente inviato da oregon
    Bisogna anche vedere se le usi bene ...



    No. O almeno, c'era un motivo ben preciso, nel codice che era in esecuzione.
    secondo me oregon le possibilità sono due:
    - o dipende dalle API
    - o dal webbrowser

    in questa routine non eseguo miliardi di cose, c'è sto webbrowser che gira per il web, aggiorno le label, e aggiorno un database, eseguo delle api.
    riguardo le procedure di connessione e uso del database sono arci-sicuro che vanno bene che sono anni che uso sempre le stesse cose.

  8. #8
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Che API? Sono necessarie?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  9. #9
    Utente di HTML.it L'avatar di mvent
    Registrato dal
    Jun 2002
    Messaggi
    230
    beh, quello che fanno queste API mi serve. se riesco a farlo senza API e in modo più semplice, magari...
    posto quello che ho nel modulo:
    codice:
    Option Explicit
    Option Base 0
    Option Compare Text
    Public Declare Function Beep Lib "kernel32" (ByVal dwFreq As Long, ByVal dwDuration As Long) As Long
    Public Declare Function CloseHandle Lib "Kernel32.dll" (ByVal Handle As Long) As Long
    Public Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
    Public Declare Function DestroyWindow Lib "user32" (ByVal HWND As Long) As Long
    Public Declare Function EnumProcesses Lib "PSAPI.DLL" (ByRef lpidProcess As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
    Public Declare Function EnumProcessModules Lib "PSAPI.DLL" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
    Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean
    Public Declare Function GetModuleFileNameExA Lib "PSAPI.DLL" (ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As String, ByVal nSize As Long) As Long
    Public Declare Function GetProcessMemoryInfo Lib "PSAPI.DLL" (ByVal hProcess As Long, ppsmemCounters As PROCESS_MEMORY_COUNTERS, ByVal cb As Long) As Long
    Public Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long
    Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal HWND As Long, ByVal lpString As String, ByVal cch As Long) As Long
    Public Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal HWND As Long) As Long
    Public Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
    Public Declare Function Process32First Lib "kernel32" (ByVal hSnapshot As Long, lppe As PROCESSENTRY32) As Long
    Public Declare Function Process32Next Lib "kernel32" (ByVal hSnapshot As Long, lppe As PROCESSENTRY32) As Long
    Public Declare Function Putfocus Lib "user32" Alias "SetFocus" (ByVal HWND As Long) As Long
    Public Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal HWND As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Public Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
    Public Declare Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" (ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String, ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
    Public Type PROCESSENTRY32
      dwSize As Long
      cntUsage As Long
      th32ProcessID As Long
      th32DefaultHeapID As Long
      th32ModuleID As Long
      cntThreads As Long
      th32ParentProcessID As Long
      pcPriClassBase As Long
      dwFlags As Long
      szExeFile As String * 260
    End Type
    Public Type OSVERSIONINFO
      dwOSVersionInfoSize As Long
      dwMajorVersion As Long
      dwMinorVersion As Long
      dwBuildNumber As Long
      dwPlatformId As Long
      szCSDVersion As String * 128
    End Type
    Public Type PROCESS_MEMORY_COUNTERS
      cb As Long
      PageFaultCount As Long
      PeakWorkingSetSize As Long
      WorkingSetSize As Long
      QuotaPeakPagedPoolUsage As Long
      QuotaPagedPoolUsage As Long
      QuotaPeakNonPagedPoolUsage As Long
      QuotaNonPagedPoolUsage As Long
      PagefileUsage As Long
      PeakPagefileUsage As Long
    End Type
    Public WebBrowser1 As Object, lblUltimo As Object, lblCodCorrente As Object
    Public MSGB99 As String, TITPROG99 As String, numHWD As Long, hProc As Long, proc As PROCESS_MEMORY_COUNTERS
    Public Const PROCESS_TERMINATE = &H1
    Public Const VER_PLATFORM_WIN32_WINDOWS = 1
    Public Const PROCESS_QUERY_INFORMATION = 1024
    Public Const PROCESS_VM_READ = 16
    Public Const TH32CS_SNAPPROCESS = &H2
    
    
    
    
    
    
    Sub Main()
      TITPROG99 = " Vassallo " & App.Major & "." & App.Minor & " "
      If App.PrevInstance Then
        MSGB99 = MsgBox("Il programma è già attivo.", vbInformation, TITPROG99)
        End
      End If
      frmPrincipale.Show
    End Sub
    
    Public Sub ChiudiFinestrelle()
      'con questa procedura chiudo le varie finestrelle che si aprono durante l'esplorazione, come per esempio
      'gli avvisi protezioni, gli errori di script, eccetera (non si può usare TerminateExe perchè non è un exe)
      numHWD = 0
      EnumWindows AddressOf EnumWindowsProc, ByVal 0&
      If numHWD > 0 Then Call DestroyWindow(numHWD)
    End Sub
    
    Public Function TerminateEXE(ByVal sEXE As String) As Boolean
    Dim lPID As Long, lProcess As Long
      Do
        lPID = GetEXEProcessID(sEXE)
        If lPID <> 0 Then
          lProcess = OpenProcess(PROCESS_TERMINATE, 0, lPID)
          Call TerminateProcess(lProcess, 0&)
          Call CloseHandle(lProcess)
        End If
      Loop Until lPID = 0
      TerminateEXE = True
    End Function
    
    Public Function CheckVersion() As Long
    Dim tOS As OSVERSIONINFO
      tOS.dwOSVersionInfoSize = Len(tOS)
      Call GetVersionEx(tOS)
      CheckVersion = tOS.dwPlatformId
    End Function
    
    Public Function GetEXEProcessID(ByVal sEXE As String) As Long
    Dim aPID() As Long, lProcesses As Long, lProcess As Long, lModule As Long, sName As String
    Dim iIndex As Integer, bCopied As Long, lSnapShot As Long, tPE As PROCESSENTRY32, bDone As Boolean
      If CheckVersion() = VER_PLATFORM_WIN32_WINDOWS Then
        lSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
        If lSnapShot < 0 Then Exit Function
        tPE.dwSize = Len(tPE)
        bCopied = Process32First(lSnapShot, tPE)
        Do While bCopied
          sName = Left$(tPE.szExeFile, InStr(tPE.szExeFile, Chr(0)) - 1)
          sName = Mid(sName, InStrRev(sName, "\") + 1)
          If InStr(sName, Chr(0)) Then
            sName = Left(sName, InStr(sName, Chr(0)) - 1)
          End If
          bCopied = Process32Next(lSnapShot, tPE)
          If StrComp(sEXE, sName, vbTextCompare) = 0 Then
            GetEXEProcessID = tPE.th32ProcessID
            Exit Do
          End If
        Loop
      Else
        ReDim aPID(255)
        Call EnumProcesses(aPID(0), 1024, lProcesses)
        lProcesses = lProcesses / 4
        ReDim Preserve aPID(lProcesses)
        For iIndex = 0 To lProcesses - 1
          lProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, aPID(iIndex))
          If lProcess Then
            If EnumProcessModules(lProcess, lModule, 4, 0&) Then
              sName = Space(260)
              Call GetModuleFileNameExA(lProcess, lModule, sName, Len(sName))
              If InStr(sName, "\") > 0 Then
                sName = Mid(sName, InStrRev(sName, "\") + 1)
              End If
              If InStr(sName, Chr(0)) Then
                sName = Left(sName, InStr(sName, Chr(0)) - 1)
              End If
              If StrComp(sEXE, sName, vbTextCompare) = 0 Then
                GetEXEProcessID = aPID(iIndex)
                bDone = True
              End If
            End If
            CloseHandle lProcess
            If bDone Then Exit For
          End If
        Next
      End If
    End Function
    
    Public Function EnumWindowsProc(ByVal HWND As Long, ByVal lParam As Long) As Boolean
    Dim sSaVe As String, RET As Long
      RET = GetWindowTextLength(HWND)
      sSaVe = Space(RET)
      GetWindowText HWND, sSaVe, RET + 1
      If Trim(sSaVe) <> "" Then
        If InStr(1, LCase(sSaVe), "avviso di protezione", vbTextCompare) > 0 Then numHWD = HWND
        If InStr(1, LCase(sSaVe), "errore nello script", vbTextCompare) > 0 Then numHWD = HWND
        If InStr(1, LCase(sSaVe), "download del file", vbTextCompare) > 0 Then numHWD = HWND
        If InStr(1, LCase(sSaVe), "windows internet explorer", vbTextCompare) > 0 Then numHWD = HWND
        If InStr(1, LCase(sSaVe), "connetti a", vbTextCompare) > 0 Then numHWD = HWND
        If InStr(1, LCase(sSaVe), "windows media player", vbTextCompare) > 0 Then numHWD = HWND
        If InStr(1, LCase(sSaVe), "errore pagina web", vbTextCompare) > 0 Then numHWD = HWND
        If InStr(1, LCase(sSaVe), "ambiente di sviluppo", vbTextCompare) > 0 Then numHWD = HWND
        If InStr(1, LCase(sSaVe), "messaggio dalla pagina", vbTextCompare) > 0 Then numHWD = HWND
      End If
      EnumWindowsProc = True   'continua enumerazione
    End Function
    
    Public Function AggiustaDimensioni(DimBytes As Long) As String
      'da bytes in KB => bytes / 1024   =====   da bytes in MB => bytes / 1024 / 1024
      AggiustaDimensioni = FormatNumber(DimBytes / 1024 / 1024, 2, vbTrue, vbFalse, vbTrue) & " MB"
    End Function
    
    Public Function ControllaUsoRam(Nome_Exe As String)
    Dim RETV As Long, RISULTATO As String, ULTI As Boolean
      hProc = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, GetEXEProcessID(Nome_Exe))
      RISULTATO = GetProcessMemoryInfo(hProc, proc, Len(proc))
      RISULTATO = "Uso Ram: " & AggiustaDimensioni(proc.WorkingSetSize) & " (" & Format(Now, "Hh:Nn") & ")"
      CloseHandle hProc
      If proc.WorkingSetSize > 60000000 Then
        'rimuovo, annullo e ri-creo l'oggetto WebBrowser
        RETV = WebBrowser1.Height
        ULTI = lblUltimo.Visible
        frmRa_Princ.Controls.Remove ("WebBrowser1")   'rimuovo l'oggetto WebBrowser
        Set WebBrowser1 = Nothing   'libero la memoria
        Set WebBrowser1 = frmRa_Princ.Controls.Add("shell.explorer.2", "WebBrowser1")
        WebBrowser1.Visible = True
        WebBrowser1.Height = RETV     'può essere a dimensioni normali o minimizzate
        WebBrowser1.Width = 14415
        WebBrowser1.Left = 120
        WebBrowser1.Top = 120
        WebBrowser1.TabIndex = 8
        'rimuovo, annullo e ri-creo l'oggetto label con gli indirizzi web
        frmRa_Princ.Controls.Remove ("lblUltimo")   'rimuovo l'oggetto lblUltimo
        Set lblUltimo = Nothing   'libero la memoria
        Set lblUltimo = frmRa_Princ.Controls.Add("VB.label", "lblUltimo", frmRa_Princ.Frame2)
        lblUltimo.Alignment = 0   'left
        lblUltimo.AutoSize = False
        lblUltimo.BackColor = &H0&  'nero
        lblUltimo.BorderStyle = 0
        lblUltimo.Caption = "Azzeramento WebBrowser in corso..."
        lblUltimo.FontName = "Tahoma"
        lblUltimo.FontBold = True
        lblUltimo.FontSize = 9
        lblUltimo.ForeColor = &HFF00&  'verde
        lblUltimo.Height = 255
        lblUltimo.Width = 11535
        lblUltimo.Left = 120
        lblUltimo.Top = 360
        lblUltimo.Visible = ULTI
        'rimuovo, annullo e ri-creo l'oggetto label con il codice corrente
        frmRa_Princ.Controls.Remove ("lblCodCorrente")   'rimuovo l'oggetto lblCodCorrente
        Set lblCodCorrente = Nothing   'libero la memoria
        Set lblCodCorrente = frmRa_Princ.Controls.Add("VB.label", "lblCodCorrente", frmRa_Princ.Frame2)
        lblCodCorrente.Alignment = 0   'left
        lblCodCorrente.AutoSize = False
        lblCodCorrente.BackColor = &H0&  'nero
        lblCodCorrente.BorderStyle = 0
        lblCodCorrente.Caption = "-"
        lblCodCorrente.FontName = "Tahoma"
        lblCodCorrente.FontBold = True
        lblCodCorrente.FontSize = 9
        lblCodCorrente.ForeColor = &HFF00&  'verde
        lblCodCorrente.Height = 255
        lblCodCorrente.Width = 10800
        lblCodCorrente.Left = 855
        lblCodCorrente.Top = 1680
        lblCodCorrente.Visible = True
      End If
      ControllaUsoRam = RISULTATO
    End Function

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.