On l'a surement tous vue au moins une ou deux fois cette erreur :
System.InvalidOperationException was unhandled
Message="Le thread appelant ne peut pas accéder à cet objet parce qu’un autre thread en est propriétaire."
...
Pourquoi appraît-elle? Quelle est sa signification exacte? Comment faire ce que l'on veux faire?
C'est simple
Dans WPF, un thread qui crée un objet en est propriétaire. L'interface, définie dans le Xaml est crée par un (et un seul) thread. Mais lequel? Peut importe !
Tout ce qu'il faut savoir, c'est qu'un Dispatcher manage ce thread, et qu'il est possible de demander à ce Dispatcher d'ajouter une oppération à la file d'attente de ce Thread.
Un exemple :
Si nous définisons cette interface simple :
<Window x:Class="Dispatcher.Window1"
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
Title="Window1" Height="300" Width="300">
<StackPanel>
<Button Name="button1" Content="Launch" Click="Button_Click"/>
<Label Name="Label1"/>
</StackPanel>
</Window>
Ce code, par exemple, ne fonctionnera pas :
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread T = new Thread(UpdateText);
T.Start();
}
private void UpdateText()
{
Thread.Sleep(1000);
Label1.Content = "label1 updated !";
}
Celui-ci, par contre, fonctionnera :
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread T = new Thread(UpdateText);
T.Start();
}
private void UpdateText()
{
Thread.Sleep(1000);
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
(ThreadStart)delegate {
Label1.Content = "label1 updated !"; });
}
this.Dispatcher vous permet de retrouver le Dispatcher de la Windows dans laquel vous travailler, il n'en existe qu'un seul par Windows.
DispatcherPriority est la priorité acordée à l'action que vous voulez entreprendre, il en existe beaucoup, elle vont de "Fait le tout de suite" à "Fait le quand tu aura le temps".