SynchronizationContextは、別のスレッドからUIを更新する方法を提供します(Sendメソッドを介して同期的に、またはPostメソッドを介して非同期に)。
次の例を見てください。
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は、UIスレッドの同期コンテキストを返します。どうすればわかりますか?すべてのフォームまたはWPFアプリの開始時に、コンテキストはUIスレッドに設定されます。WPFアプリを作成して私の例を実行すると、ボタンをクリックすると、約1秒間スリープし、ファイルのコンテンツが表示されることがわかります。UpdateTextBoxメソッドの呼び出し元(Work1)がスレッドに渡されるメソッドであるため、そうではないかもしれません。そのため、メインのUIスレッドではなく、そのスレッドをスリープさせる必要があります。Work1メソッドはスレッドに渡されますが、SyncContextであるオブジェクトも受け入れることに注意してください。これを見ると、UpdateTextBoxメソッドがWork1メソッドではなくsyncContext.Postメソッドを介して実行されていることがわかります。以下を見てください。
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread.Sleep(1000);
string text = File.ReadAllText(@"c:\temp\log.txt");
myTextBox.Text = text;
}
最後の例とこれは同じように実行されます。どちらも、ジョブを実行している間はUIをブロックしません。
結論として、SynchronizationContextはスレッドと考えてください。これはスレッドではなく、スレッドを定義します(すべてのスレッドにSyncContextがあるわけではないことに注意してください)。その上でPostまたはSendメソッドを呼び出してUIを更新するときはいつでも、それは通常、メインUIスレッドからUIを更新するのと同じです。何らかの理由で別のスレッドからUIを更新する必要がある場合は、スレッドにメインUIスレッドのSyncContextが含まれていることを確認し、実行するメソッドでそのスレッドのSendまたはPostメソッドを呼び出すだけで、すべて完了です。セットする。
これがあなたを助けることを願っています、仲間!