Zoeken…


Toegang tot een UI-element vanuit een taak

Alle UI-elementen die zijn gemaakt en zich in de hoofdthread van een programma bevinden. Toegang tot deze via een andere thread is verboden door de runtime van het .net-framework. Kortom, het is omdat alle UI-elementen threadgevoelige bronnen zijn en toegang tot een resource in een multi-threaded omgeving moet thread-safe zijn. Als deze cross thread-objecttoegang is toegestaan, zou de consistentie in de eerste plaats worden beïnvloed.

Overweeg dit scenario:

We hebben een berekening in een taak. Taken worden uitgevoerd in een andere thread dan de hoofdthread. Terwijl de berekening doorgaat, moeten we een voortgangsbalk bijwerken. Om dit te doen:

//Prepare the action
Action taskAction = new Action( () => {   
    int progress = 0;
    Action invokeAction = new Action( () => { progressBar.Value = progress; });
    while (progress <= 100) {
        progress = CalculateSomething();
        progressBar.Dispatcher.Invoke( invokeAction );
    }
} );

//After .net 4.5
Task.Run( taskAction );

//Before .net 4.5
Task.Factory.StartNew( taskAction ,
    CancellationToken.None, 
    TaskCreationOptions.DenyChildAttach, 
    TaskScheduler.Default);

Elk UI-element heeft een Dispatcher-object dat afkomstig is van de DispatcherObject voorouder (in System.Windows.Threading naamruimte). Dispatcher voert de opgegeven gemachtigde synchroon uit met de opgegeven prioriteit op de thread waaraan de Dispatcher is gekoppeld. Aangezien de uitvoering is gesynchroniseerd, moet de taak van de beller wachten op het resultaat. Dit geeft ons de mogelijkheid om int progress ook in een afgevaardigde te gebruiken.

Misschien willen we een UI-element asynchroon bijwerken en vervolgens de wijzigingen in de invokeAction :

//Prepare the action
Action taskAction = new Action( () => {   
    int progress = 0;
    Action<int> invokeAction = new Action<int>( (i) => { progressBar.Value = i; } )
    while (progress <= 100) {
        progress = CalculateSomething();
        progressBar.Dispatcher.BeginInvoke( 
            invokeAction,
            progress );
    }
} );

//After .net 4.5
Task.Run( taskAction );

//Before .net 4.5
Task.Factory.StartNew( taskAction ,
    CancellationToken.None, 
    TaskCreationOptions.DenyChildAttach, 
    TaskScheduler.Default);

Deze keer hebben we int progress ingepakt en gebruiken als een parameter voor gedelegeerde.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow