Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 17
  1. #1

    [VB.NET 2.0] Usare controllo da BackgroundWorker, eccezione

    Salve a tutti
    Sto lavorando su un controllo TreeView in un thread separato,
    quando eseguo questa riga di codice
    codice:
          twFiles.Nodes.Add("stringa")
    Mi lancia un'eccezione di tipo InvalidOperationException con la seguente descrizione:

    L'azione da eseguire sul controllo è stata chiamata dal thread sbagliato. Per eseguire l'operazione, è necessario eseguire il marshalling del thread appropriato, utilizzando Control.Invoke o Control.BeginInvoke.

    Non ho capito cosa devo fare per risolverla, e sinceramente nemmeno da cosa è causata :asd:
    Qualcuno mi può aiutare?
    N.B: Ho provato anche a impostare Control.CheckIllegalCrossThreadException su False, ma niente!
    Ciao e grazie a chi mi risponderà
    Mi contraddico facilmente, ma lo faccio così spesso che questo fa di me una persona coerente [Caparezza]
    Se la conoscenza crea problemi, non è con l'ignoranza che li si risolve [Isaac Asimov]
    >>>Visita il mio blog<<<

  2. #2
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    non puoi accedere da bgw ai controlli.
    Al massimo se la "stringa" è un valore che tiri fuori dal bgw.DoWork l'istruzione che dici la puoi far eseguire dall'handler del bgw.RunworkerCompleted

  3. #3
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,472
    Sul problema specifico, c'è questo fantastico e lungo thread a cui ho partecipato anche io che ne esamina ogni retroscena e indica come risolvere.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  4. #4
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    Mamma mia che flame (che poi poteva aver ragione "sul momento", della serie compila esegui e va bene ma se bastasse questo a dire che un programa, magari grosso, è robusto..).

    tornando a noi, trattandosi di una treeview mi vine in mente che la stessa la voresti popolare DURANTE il lavoro e non solo alla fine. Per questo dovresti usare reportprogress e onprogresschanged. E dentro quest'ultimo evento che il bgw torna al thread principale e ti consente di "toccare" i contolli. Reportprogress invece lo chiami da DoWork.
    L'esempio qui è semplicissimo: MSDN ESEMPIO lascia stare la parte xaml se non la capisci il codebheind parla da solo.

  5. #5
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    usare invoke?

    una cosa del genere:

    codice:
    void QuestoMetodo(object sender, EventArgs e)
    {
                if (control.InvokeRequired)
                {
                    //chiamo il metodo attraverso un delegato
                    control.Invoke(new Tipodelegato(QuestoMetodo), sender, e);
                }
                else
                {
                    //eseguo direttamente
                }
    }
    cosa c'è che non va qui?

  6. #6
    Grazie per il link Alka, ma è diversa la situazione, perchè modificare una TextBox è ben più semplice che modificare un TreeView (opero con .Add e i tag dei nodi).
    Metà del topic poi è un gran flame

    Originariamente inviato da U235
    usare invoke?

    una cosa del genere:

    codice:
    void QuestoMetodo(object sender, EventArgs e)
    {
                if (control.InvokeRequired)
                {
                    //chiamo il metodo attraverso un delegato
                    control.Invoke(new Tipodelegato(QuestoMetodo), sender, e);
                }
                else
                {
                    //eseguo direttamente
                }
    }
    cosa c'è che non va qui?
    Mi avevano fatto un esempio del genere... e avevo pure provato, ma non va: mi da errore esattamente nella stessa riga. Anche perchè devo fare più azioni sul TreeView, e diventa complicato.

    EDIT: Ripensandoci però, la descrizione dell'errore parla proprio di sta roba, magari è la strada giusta da seguire
    E io non ci ho capito proprio tanto , quindi magari ho sbagliato qualcosa nel codice che ho scritto. Magari me lo spiegate meglio?
    codice:
    Delegate Sub DelTwFiles(ByVal Node As TreeNode)
    
        Private Sub TwFilesSub(ByVal Node As TreeNode)
            If twFiles.InvokeRequired Then
                twFiles.Invoke(New DelTwFiles(AddressOf TwFilesSub), Node)
            End If
        End Sub
    Ho aggiunto solo questo. Forse c'è da scrivere del codice anche nel DoWork?
    Mi contraddico facilmente, ma lo faccio così spesso che questo fa di me una persona coerente [Caparezza]
    Se la conoscenza crea problemi, non è con l'ignoranza che li si risolve [Isaac Asimov]
    >>>Visita il mio blog<<<

  7. #7
    Originariamente inviato da rsdpzed
    Mamma mia che flame (che poi poteva aver ragione "sul momento", della serie compila esegui e va bene ma se bastasse questo a dire che un programa, magari grosso, è robusto..).

    tornando a noi, trattandosi di una treeview mi vine in mente che la stessa la voresti popolare DURANTE il lavoro
    Il TreeView devo popolarlo per forza separatamente, o tutta l'app mi si blocca
    Originariamente inviato da rsdpzed
    e non solo alla fine. Per questo dovresti usare reportprogress e onprogresschanged. E dentro quest'ultimo evento che il bgw torna al thread principale e ti consente di "toccare" i contolli. Reportprogress invece lo chiami da DoWork.
    L'esempio qui è semplicissimo: MSDN ESEMPIO lascia stare la parte xaml se non la capisci il codebheind parla da solo.

    Di questa parte non ho capito una parola, scrivi meglio per favore!

    P.S: Grazie per avermi risposto
    Mi contraddico facilmente, ma lo faccio così spesso che questo fa di me una persona coerente [Caparezza]
    Se la conoscenza crea problemi, non è con l'ignoranza che li si risolve [Isaac Asimov]
    >>>Visita il mio blog<<<

  8. #8
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539

    si tratta di wpf o windows form?

    se è windows form oltre al delegato devi mettere anche else con l'esecuzione del codice, se no non svolge nessuna azione.

    ma forse il problema è che tu lavori nodo per nodo e non tutta la treeeview, quindi se non sincronizzi i thread potrebbe capitare che cerchi di inserire un nodo in un altro che magari non è ancora stato creato da qualche altro thread. Non è detto che i thread vengano eseguiti nell'ordine che nella quale sono stati lanciati.

    esempio se tu lanci 3 thread in rapida sequenza, tipo il primo crea il nodo padre, il secondo un figlio, il terzo un "nipote", potrebbe capitare che senza sincronizzazione venga eseguito prima il figlio del padre e quindi cerchi di inserire un nodo in un altro che non è ancora stato creato.

  9. #9
    Originariamente inviato da U235

    si tratta di wpf o windows form?
    Form
    Originariamente inviato da U235
    se è windows form oltre al delegato devi mettere anche else con l'esecuzione del codice, se no non svolge nessuna azione.
    E quello c'è. Non è che devo chiamare qualche metodo dall'altro thread?
    Tipo
    codice:
    twFiles.Invoke(new Delegato(AddressOf MetodoWrapper),Argomenti)
    Originariamente inviato da U235
    ma forse il problema è che tu lavori nodo per nodo e non tutta la treeeview, quindi se non sincronizzi i thread potrebbe capitare che cerchi di inserire un nodo in un altro che magari non è ancora stato creato da qualche altro thread. Non è detto che i thread vengano eseguiti nell'ordine che nella quale sono stati lanciati.

    esempio se tu lanci 3 thread in rapida sequenza, tipo il primo crea il nodo padre, il secondo un figlio, il terzo un "nipote", potrebbe capitare che senza sincronizzazione venga eseguito prima il figlio del padre e quindi cerchi di inserire un nodo in un altro che non è ancora stato creato.
    Conosco la faccenda , ma il problema non si presenta perchè i nodi li modifico SOLO nel secondo thread, che uso per eseguire dei metodi asincroni.
    Mi contraddico facilmente, ma lo faccio così spesso che questo fa di me una persona coerente [Caparezza]
    Se la conoscenza crea problemi, non è con l'ignoranza che li si risolve [Isaac Asimov]
    >>>Visita il mio blog<<<

  10. #10
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    hai provato così :

    codice:
    Delegate Sub DelTwFiles(Node As TreeNode)
    
    Private Sub TwFilesSub(Node As TreeNode)
    	If twFiles.InvokeRequired Then
    		twFiles.Invoke(New DelTwFiles(TwFilesSub), Node)
    	Else
    		twFiles.Nodes.Add(Node)
    	End If
    End Sub
    cosi viene richiamato lo stesso codice, ma la seconda volta (dopo essere stato chiamato dal delegato) entra in else. Se no non fa nulla.
    oppure dividi :

    codice:
    Delegate Sub DelTwFiles(Node As TreeNode)
    
    Private Sub TwFilesSub(Node As TreeNode)
    	If twFiles.InvokeRequired Then
    		twFiles.Invoke(New DelTwFiles(EseguiTwFilesSub), Node)
            Else
    		 EseguiTwFilesSub(Node)
    	End If
    End Sub
    
    Private Sub EseguiTwFilesSub(Node As TreeNode)
    	twFiles.Nodes.Add(Node)
    End Sub

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.