wpf
Trådaffinitet åtkomst till UI-element
Sök…
Få åtkomst till ett UI-element från en uppgift
Alla UI-element skapade och finns i huvudtråden i ett program. Det är förbjudet att komma åt dessa från en annan tråd av .net-ramens körtid. I grund och botten beror det på att alla UI-element är trådkänsliga resurser och åtkomst till en resurs i en multigängad miljö kräver att det är tråd-säkert. Om denna tvärtrådobjektåtkomst är tillåten skulle konsistensen påverkas i första hand.
Tänk på detta scenario:
Vi har en beräkning som sker inom en uppgift. Uppgifter körs i en annan tråd än huvudtråden. Medan beräkningen fortsätter måste vi uppdatera en framstegsfält. Att göra detta:
//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);
Varje UI-element har ett Dispatcher-objekt som kommer från dess DispatcherObject
förfader (inuti System.Windows.Threading
namnutrymme). Dispatcher kör den specificerade delegaten synkront med den angivna prioriteten i tråden som Dispatcher är kopplad till. Eftersom exekvering synkroniseras bör samtalsuppgiften vänta på dess resultat. Detta ger oss möjlighet att använda int progress
även inom en avsändare-delegat.
Vi kanske vill uppdatera ett UI-element asynkront sedan 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);
Den här gången packade vi int progress
och använder den som en parameter för delegat.