SynchronizationContext ให้เรามีวิธีการอัปเดต UI จากเธรดอื่น (ซิงโครนัสผ่านวิธีการส่งหรือแบบอะซิงโครนัสผ่านวิธีการโพสต์)
ดูตัวอย่างต่อไปนี้:
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 ถูกเรียกใช้ผ่านเมธอด syncContext.Post ไม่ใช่เมธอด Work1 ดูสิ่งต่อไปนี้:
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) เมื่อใดก็ตามที่เราเรียกใช้วิธีการโพสต์หรือส่งเพื่ออัปเดต UI ก็เหมือนกับการอัปเดต UI ตามปกติจากเธรด UI หลัก หากด้วยเหตุผลบางประการคุณจำเป็นต้องอัปเดต UI จากเธรดอื่นตรวจสอบให้แน่ใจว่าเธรดมี SyncContext ของเธรด UI หลักและเพียงแค่เรียกใช้วิธีการส่งหรือโพสต์ด้วยวิธีการที่คุณต้องการดำเนินการเท่านี้คุณก็พร้อมแล้ว ชุด.
หวังว่านี่จะช่วยคุณได้เพื่อน!