Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it
    Registrato dal
    Apr 2008
    Messaggi
    93

    [C#]invoke-delegate utilizzo

    salve ragazzi, vi scrivo perchè faccio fatica a risolvere un problema.
    sono incappato nell'errore di voler modificare una label del winform principale da un thread esterno.ovviamente ho ricevuto l'errore del thread-cross dato che cn windows è impossibile modificare elementi del form pricipale da thread diversi.
    detto questo ho visto in internet che il tutto si dovrebbe risolvere tramite l'utilizzo dei delegate e di invoke, però nn riesco proprio a capire come fare...
    qui è il pezzo in cui richiamo il thread dal form pricipale all'interno della difinizione della label5
    codice:
    ...
    this.label5.Name = "label5";             
    this.label5.Size = new System.Drawing.Size(142, 51);             
    this.label5.TabIndex = 6;                        
    Thread t = new Thread(this.timer);             
    t.Start();
    ...
    qui invece la funzione timer
    codice:
    void timer()         
    {             
    int s=0, m=0;             
    while (m < 15)            
    {               
    this.label5.Text = m + ":" + s;
    Thread.Sleep(1000);                
    s++;                 
    if (s == 60) m++;             
    }         
    }
    grazie

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

  3. #3
    Utente di HTML.it
    Registrato dal
    Apr 2008
    Messaggi
    93
    quindi nel mio caso devo crare un delegate
    codice:
    public delegate void timerdel();         
    public timerdel myDelegate;
    e poi come creo la corrispondente invoke?
    codice:
    myDelegate = new timerdel(this.timer);             
    Thread t = new Thread(this.Invoke(this.myDelegate));
    cosi non va bene...

  4. #4
    Un controllo WindowForms può essere modificato solo dal thread che l'ha creato, quindi per poterlo moificare da un altro thread bisogna creare un delegate che deve essere passato al form tramite il metodo invoke, tale metodo non fa altro che eseguire il delagate nel proprio thread.
    andiamo al codice:

    bisogna prima creare il delegate:
    codice:
    public delegate void aggiornaLabel(string str, Label label);
    questo delegate accetta in ingresso la stringa che vuoi inserire nel label e il label, in modo che puoi riutillizzarlo anche per altri label. (Il Delegate va inserito al di fuori della classe, così lo puoi utilizzare ovunque)

    Ora hai bisogno di un metodo per poter istanziare il delegate, il metodo deve aver gli stesi tipi di argomenti:

    codice:
            
            public void updateLabel(String str, Label label)
            {
                label.Text = str;
            }
    questo metodo lo puoi inserire dove vuoi ma per come ti scriverò la prossima parte deve stare nella classe form.

    ora non ci resta che passare al metodo invoke dell'istanza della classe form l'istanza del delegate:
    codice:
    this.myform.Invoke(new aggiornaLabel(this.form.updateLabel), "mia Stringa", this.myform.myLabel);

    per poter capire il concetto devi capire bene che sono i delegate e come utillizzarli,
    il concetto di base è questo:

    I delegate ci permettono di passare un metodo ad altri metodi come argomento

    altri linguaggi permettono di farlo diversamente es

    Action Script di Flash ha un tipo "Function" che ci permette di mettere un metodo in una variabile di quel tipo.
    PHP come anche il c ha i metoi callback che permettono di chiamare un metodo tramite una stringa

    a io parere l'approccio ActionScript è olto più semplice

  5. #5
    Utente di HTML.it
    Registrato dal
    Apr 2008
    Messaggi
    93
    GRANDE!!
    grazie mille per l'esauriente spiegazione.oltre a funzionare mi hai chiarito le idee, che è la cosa più importante.
    se posso ti faccio un altra domanda al volo senza aprire un altro topic.
    chiudendo il form principale con la X questo si ferma ma il thread da me lanciato resta in esecuzione dando errore dato che invoke opera su qualcosa che nn esiste più.
    come è meglio procedere per chiudere il thread insieme al form?

  6. #6
    Facendo riferimento ai metodi statici di Thread si agisce sul thread corrente invece utilizzando l'istanza di un thread si fa riferimento a quel thread:

    Thread.Abort(); //ferma il thread corrente

    mioThread.Abort()//ferma il thread dell'istanza alla quale si riferisce mioThread

    un'altra cosa che può servirti è la proprietà isAlive che ti dice se un thread è vivo o è morto

    se vai su msdn c'è tutto ed è molto + chiaro di me

  7. #7
    Utente di HTML.it
    Registrato dal
    Apr 2008
    Messaggi
    93
    l'utilizzo dell'abort lo conosco, semplicemente non riesco a collegarlo all'evento di chiusura...mi spiego, non so quale sia il gestore dell'evento chiusura del form.ho provato con
    codice:
    private void Form2_Closing(object sender, System.ComponentModel.CancelEventArgs e)         
    {            
           closeth();//mia funzione che richiama l'abort di quel thread         
    }
    ma non funziona.se dalla visuale progettazione del mio form clicco due volte su un componente, mi si apre in automatico la funzione che gestisce l'evento, ma se clicco 2 volte sulla X mi apre form_load che gestisce il load del forum non la chiusura.qundi nn so quale sia il metodo che gestisce la chisura del form...

  8. #8
    Selezoni la form dalla quale vuoi attaccare il metodo per l'evento,
    dalla finestra proprietà vedi c'è un pulsante tipo fulmine, cliccaci sopra e ti verra fuori la lista di tutti gli eventi, scegli quello che t'interessa.

  9. #9
    Utente di HTML.it
    Registrato dal
    Apr 2008
    Messaggi
    93
    che dire...grazie mille!!
    tutto risolto

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.