Domanda

Capisco che in .NET, si ha la necessità di utilizzare Control.Invoke (delegato) per eseguire operazioni su un controllo. Questo mi ha portato a chiedersi in cui ambienti Invoke è effettivamente necessaria. Per quanto ne so, non è stato richiesto nelle versioni precedenti di, diciamo, Visual Basic e Pascal. In particolare, qual è lo stato di Java (possibilmente versione-dipendente?) E "vecchio stile" finestre di programmazione GUI (lettura manualmente la coda di messaggi)?

È stato utile?

Soluzione

Nella maggior parte delle lingue Invoke per le operazioni di GUI è necessario. In Java v'è SwingUtilities.invokeLater . In realtà un metodo del genere sarebbe necessaria in qualsiasi ambiente se vengono utilizzati più di un thread. La ragione è che il thread principale dell'interfaccia utente esegue un meccanismo di notifica degli eventi. Un secondo filo per poter interagire con questo meccanismo deve essere in qualche modo sincronizzato con esso.

Si invocano metodi sono in realtà un vantaggio per lo sviluppatore. In piattaforme che non esistono, non significa che è consentito di accedere agli elementi dell'interfaccia utente da un thread diverso. Si può solo dire che lo sviluppatore dovrebbe attuare un meccanismo personalizzato (l'invio di eventi) di farlo. Codice interfaccia utente è molto raramente thread-safe. Ho lavorato con molte piattaforme e tecnologie e sto sempre seguendo questa regola:. Toccare l'interfaccia utente da un unico filo

Altri suggerimenti

Ti sbagli. Control.Invoke non è richiesto per eseguire operazioni su un controllo.

Control.Invoke è uno strumento utile per aiutare il codice marshall di là dei confini della discussione, ma non è l'unico modo per farlo. Vedrete questo usato più spesso quando si fa un po 'di lavoro in un thread in background.

Quando si chiama il codice da un thread in background che deve aggiornare un controllo finestra (vale a dire, un controllo che ha una maniglia finestra di Windows ed elabora messaggi tramite pompa di messaggio), cambia le sue proprietà, o qualche altra manipolazione del controllo allora si deve passare il controllo al thread MessagePump e Control.Invoke è un modo utile per acocmplish che.

tutti i programmi che girano sotto Windows, non è possibile chiamare le funzioni che i controlli di aggiornamento su un thread in background. Alcune lingue possono gestire questo dettaglio in sottofondo, ma non so di qualsiasi che lo fanno.

Invoke è solo un wrapper per l'API Win32 PostMessage. Solo il thread che possiede una finestra è consentito di accedere alla finestra. Questa è l'eredità va tutta la strada fino a quando Windows era a thread singolo. Ciò significa che PostMessage è il modo corretto per accedere a una vera finestra su Windows non importa ciò che si sta utilizzando (VB6, Delphi, NET, o qualsiasi altra cosa), ma i diversi linguaggi di programmazione fornisci wrapper per rendere la vita più facile per noi.

In realtà, no. E 'necessaria solo se si è GUI è in esecuzione più di 1 thread. Con WinForm (WPF) e applicazioni GUI è in esecuzione su un singolo thread STA filettato (questo risale al COM e non mi chiedere perché è così, perché io non so onestamente).

Se si tenta di chiamare gli oggetti creati sul thread STA da un thread diverso, ci sono controlli in atto per assicurarsi che viene generata un'eccezione. Questo stesso vale con WPF, anche se, WPF rende molto più elegante.

In ogni caso, si può effettivamente controllare quando è richiesto Invoke perché c'è una proprietà per questo. Questo modello è stato suggerito per aiutare con la gestione diversi thread in applicazioni WinForm.

public void MyTextSetMethod(string text)
{
    if(control.InvokeRequired)
    {
        control.Invoke(new Action<string>(MyTextSetMethod), text);
    }
    else
    {
        control.Text = text;
    }
}

Il codice di cui sopra prevede un tutto metodo di fissazione la proprietà Text, è possibile personalizzare questo per soddisfare le vostre esigenze.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top