Pagina 2 di 3 primaprima 1 2 3 ultimoultimo
Visualizzazione dei risultati da 11 a 20 su 22
  1. #11
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    105
    Ma scusate una cosa, se io creo 3 form separate, ogni form è un thread separato? oppure vengono gestite tutte e 3 dal thread della form principale?

    Perchè io ho 3 form:
    la principale dove ci sono le impostazioni per settare la camera,
    una form di preview dove c'è il flusso dati della camera,
    e la terza form dove dovrebbe esserci l'output delle immagini (elaborate dal thread di elaborazione) prese dalla clipboard.

    Ora il punto è che se io richiamo dal thread di elaborazione (che è stato avviato nella classe della form principale) il comando "FinestraElaborazione.InvokeRequired" il comando da sempre la finestra occupata, lo stesso vale per la finestra di preview, mentre se scrivo "FinestraPrincipale.InvokeRequired" l'accesso alla finestra lo da senza problemi.
    Nessuno può illuminarmi?
    (vi posterei tutto il codice ma mi sa ke è troppo lungo )

  2. #12
    Utente di HTML.it
    Registrato dal
    Apr 2009
    Messaggi
    970
    Originariamente inviato da Adanf
    Ma scusate una cosa, se io creo 3 form separate, ogni form è un thread separato? oppure vengono gestite tutte e 3 dal thread della form principale?
    Vengono gestite tutte e tre le form dal Main Thread. Se sei curioso di vedere come vengono gestiti i/il thread della tua applicazione basta che quando sei in modalità debug attivi la finestra Thread nel menù Debug\Windows\Thread.

    Ora il punto è che se io richiamo dal thread di elaborazione (che è stato avviato nella classe della form principale) il comando "FinestraElaborazione.InvokeRequired" il comando da sempre la finestra occupata, lo stesso vale per la finestra di preview, mentre se scrivo "FinestraPrincipale.InvokeRequired" l'accesso alla finestra lo da senza problemi.
    Nessuno può illuminarmi?
    (vi posterei tutto il codice ma mi sa ke è troppo lungo )
    Scusa non ho capito cosa vuoi dire.

    Un consiglio, ti crei una classe che gestisce l'elaborazione dei frame eventualmente usando il multiThread e quando devi comunicare qualcosa all'UI lo fai tramite un'evento della classe. Chiaramente se l'evento viene scatenato da un Thread separato dal quello della UI è necessario gestire correttamente il codice per non incorrere in opperazioni cross-thread non valide.

    Per assurdo se vuoi semplicare un po tutto potresti anche utilizzare il BackGroundWorker nella classe.....

    codice:
      Dim WithEvents bw As System.ComponentModel.BackgroundWorker
    Sbagliare è umano, perseverare è diabolico.

  3. #13
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    105
    Originariamente inviato da Pirelli72
    Vengono gestite tutte e tre le form dal Main Thread. Se sei curioso di vedere come vengono gestiti i/il thread della tua applicazione basta che quando sei in modalità debug attivi la finestra Thread nel menù Debug\Windows\Thread.
    non al trovo quella finestra, forse perchè ho la versione 2008 express edition?



    Originariamente inviato da Pirelli72

    Per assurdo se vuoi semplicare un po tutto potresti anche utilizzare il BackGroundWorker nella classe.....
    codice:
      Dim WithEvents bw As System.ComponentModel.BackgroundWorker
    Lo so, infatti avevo intenzione di usarlo, ma solo per far funzionare il programma anche iconato più che altro, ma non penso sia quello il mio problema.

    Allora per assurdo anche usando il delegato, va tutto, nella form di output ho aggiunto una textbox per verificare che funzioni e aggiungendo un breakpoit in corrispondenza di questo punto ho verificato che il comando viene eseguito (cioè copia il testo nell'oggetto textbox), ma sulla form non appare il cambiamento!
    Com'è possibile? cioè l'oggetto textbox "cambia" ma non viene visualizzato sulla form? anche usando il refresh() della stessa?
    Boh non so più che fare, sto diventando pazzo

    Posto questo pezzo di codice dove mi da quello strano "errore":

    Parte del codice della FinestraPrincipale:
    codice:
      'avvia l'elaborazione di un frame della fonte video
        Private Sub BElaborazione_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BElaborazione.Click
            thr = New Thread(New ThreadStart(AddressOf ElaboraFrame))
            If ((FinestraAnteprima.Visible = False Or FinestraAnteprima.WindowState = FormWindowState.Minimized) And FinestraNascosta.Visible = False) Then
                FinestraNascosta.Visible = True
                SetUpVideo(FinestraNascosta.PBNascosta)
            End If
            Ridimensiona(FinestraElaborazione.PBElaborazione)
            FinestraElaborazione.Enabled = True
            FinestraElaborazione.Visible = True
    
            thr.SetApartmentState(ApartmentState.STA)
            thr.Start()
            thr.Join()
        End Sub
    
        'corpo elaborazione frame su thread separato
        Private Sub ElaboraFrame()
            Dim frame As Bitmap
            Dim bmap As Image
            'copiamo l'immagine nella clipboard---
            SendMessage(hWnd, WM_CAP_EDIT_COPY, 0, 0)
            'prendiamo l'immagine dalla clipboard
            bmap = Clipboard.GetImage
            frame = New Bitmap(bmap)
            'Label2.Text = frame.GetPixel(1, 1).ToArgb.ToString
            For i As Integer = 0 To frame.Height - 1
                For j As Integer = 0 To frame.Width - 1
                    If (frame.GetPixel(j, i).R > 0 And frame.GetPixel(j, i).G > 0 And frame.GetPixel(j, i).B > 0) Then
                        frame.SetPixel(j, i, Color.Red)
                    End If
                Next
            Next
            FinestraElaborazione.disegno(frame)
            thr.Abort()
        End Sub
    Codice della FinestraElaborazione:
    codice:
    Public Class FinestraElaborazione
        Public Delegate Sub disegnoCallback(ByVal frame As Bitmap)
        Dim disegnoMD As New disegnoCallback(AddressOf disegno)
    
        
        Private Sub FinestraElaborazione_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.Top = FinestraPrincipale.Top + 50
            Me.Left = FinestraPrincipale.Right
            FinestraPrincipale.NoScala()
        End Sub
    
        Public Sub disegno(ByVal frame As Bitmap)
            '-- verifico se è necessario invocare
            If Me.InvokeRequired Then
                '-- se è necessario, chiamo il delegato che rimanda alla stessa sub
                Me.BeginInvoke(disegnoMD)
            Else
                '-- quì verrà eseguito il codice dal Thread Corretto
                ' Me.PBElaborazione.Image = frame
                Me.Label1.Text = "prova" '<--- qui la stringa prova viene copiata nell'oggetto textbox, ma sulla form l'oggetto Label1 non cambia! (cioè rimane con la scritta label1)
            End If
        End Sub
    End Class
    Questa è l'ultima spiagga, poi abbandonerò tutto perchè non so più che fare.

  4. #14
    Utente di HTML.it
    Registrato dal
    Apr 2009
    Messaggi
    970
    codice:
    Private Sub BElaborazione_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BElaborazione.Click
            thr = New Thread(New ThreadStart(AddressOf ElaboraFrame))
            If ((FinestraAnteprima.Visible = False Or FinestraAnteprima.WindowState = FormWindowState.Minimized) And FinestraNascosta.Visible = False) Then
                FinestraNascosta.Visible = True
                SetUpVideo(FinestraNascosta.PBNascosta)
            End If
            Ridimensiona(FinestraElaborazione.PBElaborazione)
            FinestraElaborazione.Enabled = True
            FinestraElaborazione.Visible = True
    
            thr.SetApartmentState(ApartmentState.STA)
            thr.Start()
            thr.Join()
        End Sub
    Primo quel thr.Join() non ha senso messo li in quel modo perchè dopo non c'è nessun codice da elaborare.

    codice:
    Public Sub disegno(ByVal frame As Bitmap)
            '-- verifico se è necessario invocare
            If Me.InvokeRequired Then
                '-- se è necessario, chiamo il delegato che rimanda alla stessa sub
                Me.BeginInvoke(disegnoMD)
            Else
                '-- quì verrà eseguito il codice dal Thread Corretto
                ' Me.PBElaborazione.Image = frame
                Me.Label1.Text = "prova" '<--- qui la stringa prova viene copiata nell'oggetto textbox, ma sulla form l'oggetto Label1 non cambia! (cioè rimane con la scritta label1)
            End If
        End Sub
    A me questo codice non funziona, mi ritorna 'Mancata corrispondenza del numero dei parametri'

    codice:
    Delegate Sub UpdateUIHandler(ByVal frame As Bitmap)
    
    Public Sub disegno(ByVal frame As Bitmap)
            If Me.InvokeRequired Then       
                Dim handler As New UpdateUIHandler(AddressOf disegno)
                Dim args() As Object = {frame }
                Me.BeginInvoke(handler, args)
            Else      
               PBElaborazione.Image = frame   
        End Sub
    Questo funziona.

    Il consiglio di creare una classe con gli eventi? No??
    Sbagliare è umano, perseverare è diabolico.

  5. #15
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    105
    Originariamente inviato da Pirelli72

    codice:
    Delegate Sub UpdateUIHandler(ByVal frame As Bitmap)
    
    Public Sub disegno(ByVal frame As Bitmap)
            If Me.InvokeRequired Then       
                Dim handler As New UpdateUIHandler(AddressOf disegno)
                Dim args() As Object = {frame }
                Me.BeginInvoke(handler, args)
            Else      
               PBElaborazione.Image = frame   
        End Sub
    Ecco ho provato a mettere il tuo codice al posto del mio e niente, continua a dare lo stesso errore, cioè o meglio non da nulla.

    Il consiglio di creare una classe con gli eventi? No??
    In che senso? per l'elaborazione?
    a proposito tu che versione hai di visual studio? io ho la 2008 express edition magari è quello il problema.

  6. #16
    Utente di HTML.it
    Registrato dal
    Apr 2009
    Messaggi
    970
    Ormai mi sono perso nella discussione e non capisco se il tuo codice ti solleva qualche eccezione o meno.
    Io utilizzo VS2008 V9.0 RTM.

    A questo punto ti conviene postare tutto il codice che utilizzi e lo provo pure io (se vuoi).
    Sbagliare è umano, perseverare è diabolico.

  7. #17
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    105
    Originariamente inviato da Pirelli72
    A questo punto ti conviene postare tutto il codice che utilizzi e lo provo pure io (se vuoi).
    Lo posterei pure, ma è troppo lungo e non mi fa inviare il messaggio.
    Forse in PM non c'è limite di caratteri?

    p.s.: ho postato i file .vb su megaupload e rapidshare, prova a vedere se riesci a scaricarli

    http://www.megaupload.com/?d=90CYB113

    http://rapidshare.com/files/419807440/ProgettoCam.zip

    grazie dell'aiuto Pirelli72

  8. #18
    Utente di HTML.it
    Registrato dal
    Apr 2009
    Messaggi
    970
    Ho scaricato il progetto ma qui a casa non ho la cam per cui nell'elaborazione ho sostituito l'immagine della cam con un file su disco.
    Non ti sei accorto che nella sub:

    codice:
    Public Sub disegno(ByVal frame As Bitmap)
            '-- verifico se è necessario invocare
            If Me.InvokeRequired Then
                '-- se è necessario, chiamo il delegato che rimanda alla stessa sub
                Dim disegnoMD As New disegnoCallback(AddressOf disegno)
                Dim args() As Object = {frame}
                Me.BeginInvoke(disegnoMD, args)
            Else
                '-- quì verrà eseguito il codice dal Thread Corretto
                PBElaborazione.Image = frame
                Label1.Text = "prova"
                frame.Save("C:\full2.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)
                PBElaborazione.Image = Image.FromFile("C:\full2.jpg")
            End If
        End Sub
    il Me.InvokeRequired è false anche se teoricamente dovrebbe essere True? Infatti guardando la famosa finestra di gestione dei Thread quando viene richiamata la sub Disegno essa si trova effettivamente in un'altro Thread, ovvero quello di lavoro in cui effettui l'analisi del frame, ma nonostante ciò il Me.InvokeRequired è False per cui non viene chiamato successivamente il delegato. Il problema è quello.

    Per risolvere il problema prima di inviare il frame alla Picturebox nella finestra di elaborazione devi tornare nel MainThread quando sei ancora sei ancora nella Finestra principale e poi inviare il frame , ad esempio:

    codice:
    Private Sub ElaboraFrame()
            Dim frame As Bitmap
            Dim bmap As Image
            'copiamo l'immagine nella clipboard---
            SendMessage(hWnd, WM_CAP_EDIT_COPY, 0, 0)
            'prendiamo l'immagine dalla clipboard
            'bmap = Clipboard.GetImage
            bmap = Image.FromFile("C:\full.jpg")
            frame = New Bitmap(bmap)
            'Label2.Text = frame.GetPixel(1, 1).ToArgb.ToString
            For i As Integer = 0 To frame.Height - 1
                For j As Integer = 0 To frame.Width - 1
                    If (frame.GetPixel(j, i).R > 0 And frame.GetPixel(j, i).G > 0 And frame.GetPixel(j, i).B > 0) Then
                        frame.SetPixel(j, i, Color.Red)
                    End If
                Next
            Next
    'Mia modifica*************************
            disegno(frame)
    'Fine mia modifica**********************
        End Sub
    
        Delegate Sub disegnoCallback(ByVal frame As Bitmap)
        Public Sub disegno(ByVal frame As Bitmap)
            '-- verifico se è necessario invocare
            If Me.InvokeRequired Then
                '-- se è necessario, chiamo il delegato che rimanda alla stessa sub
                Dim disegnoMD As New disegnoCallback(AddressOf disegno)
                Dim args() As Object = {frame}
                Me.BeginInvoke(disegnoMD, args)
            Else
                '-- quì verrà eseguito il codice dal Thread Corretto
                FinestraElaborazione.disegno(frame)
            End If
        End Sub
    Così funziona ma ti ripeto il codice fatto così è poco leggibile.
    Ti consiglio di riscriverlo meglio utilizzando una classe per l'eleborazione e gli eventi per le notifiche.
    Sbagliare è umano, perseverare è diabolico.

  9. #19
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    105
    Grazie ancora dell'aiuto pirelli72, te ne sono grato, però mi sorge un dubbio, ma così come l'hai messa tu la funzione che elabora il frame adesso non parte più sotto un thread separato o sbaglio?
    Perchè a me serviva proprio quello, che partisse sotto un'altro thread.
    Mi ero ache accorto del fatto che l'invoke dava sempre false (l'ho anche scritto in un paio di post fa), però mi sembrava strano che non avviasse l'invoke, e mi è tutt'ora strano, visto che la finestra non è usata fino alla chiamata di quella funzione.
    Cmq se non è possibile perchè non riesce a richiamare l'invoke sotto una'ltro thread vabbò lo cercherò di fare diversamente.

    Grazie mille ancora

  10. #20
    Utente di HTML.it
    Registrato dal
    Apr 2009
    Messaggi
    970
    codice:
    Grazie ancora dell'aiuto pirelli72, te ne sono grato, però mi sorge un dubbio, ma così come l'hai messa tu la funzione che elabora il frame adesso non parte più sotto un thread separato o sbaglio?
    Non ho modificato altro, elaborazione del frame avviene sempre in un Thread separato, la modifica che ho fatto io consiste nel tornare nel MainThread nella finistra principale invece che nella finestra di elaborazione.
    Sbagliare è umano, perseverare è diabolico.

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.