SynchronizationContext ci fornisce un modo per aggiornare un'interfaccia utente da un thread diverso (in modo sincrono tramite il metodo Send o in modo asincrono tramite il metodo Post).
Dai un'occhiata al seguente esempio:
private void SynchronizationContext SyncContext = SynchronizationContext.Current;
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread thread = new Thread(Work1);
thread.Start(SyncContext);
}
private void Work1(object state)
{
SynchronizationContext syncContext = state as SynchronizationContext;
syncContext.Post(UpdateTextBox, syncContext);
}
private void UpdateTextBox(object state)
{
Thread.Sleep(1000);
string text = File.ReadAllText(@"c:\temp\log.txt");
myTextBox.Text = text;
}
SynchronizationContext.Current restituirà il contesto di sincronizzazione del thread dell'interfaccia utente. Come faccio a saperlo? All'inizio di ogni modulo o app WPF, il contesto verrà impostato sul thread dell'interfaccia utente. Se crei un'app WPF ed esegui il mio esempio, vedrai che quando fai clic sul pulsante, rimane in sospensione per circa 1 secondo, quindi mostrerà il contenuto del file. Potresti aspettarti che non lo faccia perché il chiamante del metodo UpdateTextBox (che è Work1) è un metodo passato a un thread, quindi dovrebbe dormire quel thread non il thread dell'interfaccia utente principale, NOPE! Anche se il metodo Work1 viene passato a un thread, notare che accetta anche un oggetto che è SyncContext. Se lo guardi, vedrai che il metodo UpdateTextBox viene eseguito attraverso il metodo syncContext.Post e non il metodo Work1. Dai un'occhiata a quanto segue:
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread.Sleep(1000);
string text = File.ReadAllText(@"c:\temp\log.txt");
myTextBox.Text = text;
}
L'ultimo esempio e questo esegue lo stesso. Entrambi non bloccano l'interfaccia utente mentre fa lavori.
In conclusione, pensa a SynchronizationContext come un thread. Non è un thread, definisce un thread (Nota che non tutti i thread hanno un SyncContext). Ogni volta che chiamiamo il metodo Post o Send su di esso per aggiornare un'interfaccia utente, è proprio come aggiornare l'interfaccia utente normalmente dal thread dell'interfaccia utente principale. Se, per alcuni motivi, devi aggiornare l'interfaccia utente da un thread diverso, assicurati che il thread abbia SyncContext del thread dell'interfaccia utente principale e chiama semplicemente il metodo Send o Post su di esso con il metodo che desideri eseguire e sei tutto impostato.
Spero che questo ti aiuti, amico!