Saya telah membaca banyak artikel pengantar tentang cara memperbarui antarmuka utama di utas latar belakang, dan kebanyakan dari mereka menggunakan Control.Invoke dan Control.BeginInvoke. Ini adalah solusi yang baik, tetapi ada dua masalah:
1. Anda harus mereferensikan System.Windows.Forms, lalu menggunakan System.Windows.Forms
2. Struktur kode relatif berantakan. (Sebenarnya, ini juga disebabkan oleh #1)
Microsoft menawarkan solusi lain yang lebih elegan, yaitu System.Threading. SinkronisasiKonteks。 Seperti yang Anda lihat, itu tidak ada di nameapce System.Windows.Forms, jadi kita dapat menggunakannya dengan benar di BusinessLaryer, Controler, dan bahkan modul.
Dan sangat nyaman digunakan, Anda hanya perlu fokus pada dua metode berikut:
1. Kirim: Mengirim permintaan pembaruan antarmuka ke utas utama, memblokir utas saat ini hingga kembali.
2. Posting: Mengirim permintaan pembaruan antarmuka ke utas utama tanpa memblokir utas saat ini.
Faktanya, semuanya adalah metode yang sama, kecuali bahwa send sinkron dan post bersifat asinkron
Sebelum formulir Form1 = Form1( baru), objek SynchronizationContext kosong, dan ketika formulir Form1 dibuat, objek SynchronizationContext ditambahkan ke utas ini. Jadi jawabannya adalah ketika objek Control dibuat, objek SynchronizationContext juga dibuat dan dilampirkan ke utas. Semua saat menggunakan formulir InitializeComponent(); Setelah ini selesai, itu bisa mendapatkan objek yang tidak NULL
Terakhir, perbedaan antara metode Sendt() dan Post() dari SynchronizationContext:
Send() diimplementasikan hanya dengan memanggil delegasi pada utas saat ini (panggilan sinkron). Artinya, utas UI langsung dipanggil pada subutas untuk dieksekusi, dan subutas akan terus dijalankan setelah eksekusi utas UI selesai.
Post() diimplementasikan dengan memanggil delegasi pada kumpulan utas (panggilan asinkron). Ini karena subthread akan menemukan utas dari kumpulan utas untuk menyetel utas UI, dan subutas akan langsung mengeksekusi kodenya sendiri tanpa menunggu utas UI selesai. Kode pengujian:
Hasil:
Utas utama UI: 1 Benang: 5 SinkronisKonteks:1
Ringkasan:Objek SynchronizationContext pada thread UI, baik yang dipanggil di thread utama atau di thread, akan dijalankan pada thread utama, jadi ketika ada banyak kode yang memakan waktu, itu akan menyebabkan antarmuka UI macet atau mati palsu!
SebenarnyaUtas UI tidak menggunakan kelas SynchronizationContext, tetapi WindowsFormsSynchronizationContextDongdong ini.
System.Threading.SynchronizationKode sumber konteks:
Kode sumber WindowsFormsSynchronizationContext:
|