Saya mendengar di suatu tempat bahwa menunggu async C # 5 akan sangat luar biasa sehingga Anda tidak perlu khawatir melakukan hal ini:
if (InvokeRequired)
{
BeginInvoke(...);
return;
}
// do your stuff here
Sepertinya panggilan balik dari operasi menunggu akan terjadi di utas asli si penelepon. Telah dikemukakan beberapa kali oleh Eric Lippert dan Anders Hejlsberg bahwa fitur ini berasal dari kebutuhan untuk membuat UI (terutama UI perangkat sentuh) lebih responsif.
Saya pikir penggunaan umum fitur tersebut akan menjadi sesuatu seperti ini:
public class Form1 : Form
{
// ...
async void GetFurtherInfo()
{
var temperature = await GetCurrentTemperatureAsync();
label1.Text = temperature;
}
}
Jika hanya panggilan balik yang digunakan maka pengaturan teks label akan memunculkan pengecualian karena itu tidak dijalankan di utas UI.
Sejauh ini saya tidak dapat menemukan sumber daya yang mengkonfirmasi hal ini. Adakah yang tahu tentang ini? Apakah ada dokumen yang menjelaskan secara teknis bagaimana ini akan bekerja?
Harap berikan tautan dari sumber yang dapat dipercaya, jangan hanya menjawab "ya".
sumber
await
fungsi. Ini hanya banyak gula sintaksis untuk kelanjutan lewat . Mungkin ada beberapa perbaikan lain yang tidak terkait dengan WinForms yang seharusnya membantu? Itu akan jatuh di bawah kerangka NET. Itu sendiri, meskipun, dan bukan C # khusus.Jawaban:
Saya pikir Anda membuat beberapa hal bingung, di sini. Apa yang Anda minta sudah mungkin digunakan
System.Threading.Tasks
,async
danawait
pada C # 5 hanya akan memberikan sedikit gula sintaksis yang lebih baik untuk fitur yang sama.Mari kita gunakan contoh Winforms - jatuhkan tombol dan kotak teks di formulir dan gunakan kode ini:
Jalankan dan Anda akan melihat bahwa (a) tidak memblokir utas UI dan (b) Anda tidak mendapatkan kesalahan "operasi lintas-benang yang tidak sah" seperti biasa - kecuali Anda menghapus
TaskScheduler
argumen dari yang terakhirContinueWith
, di yang mana Anda akan.Ini adalah gaya passing kelanjutan standar-rawa . Keajaiban terjadi di
TaskScheduler
kelas dan khususnya instance diambil olehFromCurrentSynchronizationContext
. Lewati ini ke kelanjutan apa pun dan Anda memberi tahu bahwa kelanjutan harus berjalan pada utas apa pun yang disebutFromCurrentSynchronizationContext
metode - dalam hal ini, utas UI.Penunggu sedikit lebih canggih dalam arti bahwa mereka menyadari utas mana yang mereka mulai dan utas mana kelanjutan yang perlu terjadi. Jadi kode di atas dapat ditulis sedikit lebih alami:
Kedua harus terlihat sangat mirip, dan pada kenyataannya mereka yang sangat mirip. The
DelayedAddAsync
Metode sekarang mengembalikanTask<int>
bukan sebuahint
, sehinggaawait
hanya menampar lanjutan ke setiap salah satu dari mereka. Perbedaan utama adalah bahwa ia meneruskan konteks sinkronisasi pada setiap baris, jadi Anda tidak harus melakukannya secara eksplisit seperti yang kami lakukan pada contoh terakhir.Secara teori perbedaannya jauh lebih signifikan. Dalam contoh kedua, setiap baris tunggal dalam
button1_Click
metode ini sebenarnya dieksekusi di utas UI, tetapi tugas itu sendiri (DelayedAddAsync
) berjalan di latar belakang. Pada contoh pertama, semuanya berjalan di latar belakang , kecuali untuk penugasantextBox1.Text
yang telah kami lampirkan secara eksplisit ke konteks sinkronisasi utas UI.Itulah yang benar-benar menarik
await
- fakta bahwa seorang penunggu dapat masuk dan keluar dari metode yang sama tanpa memblokir panggilan. Anda panggilawait
, utas saat ini kembali ke pemrosesan pesan, dan ketika selesai, penunggu akan mengambil tepat di mana itu tinggalkan, di utas yang sama ditinggalkan di. Tapi dalam hal AndaInvoke
/BeginInvoke
kontras dalam pertanyaan, saya Saya menyesal mengatakan bahwa Anda seharusnya sudah berhenti melakukan itu sejak lama.sumber
ArrayList
kelas dalam kode baru. Saya masih memiliki pengalaman dengan RX, saya sendiri. Orang-orang mempelajari apa yang perlu mereka ketahui dan membagikan apa yang sudah mereka ketahui, bahkan jika apa yang sudah mereka ketahui sudah ketinggalan zaman. Jawaban ini mungkin kedaluwarsa dalam beberapa tahun.Ya, untuk utas UI, panggilan balik dari operasi tunggu akan terjadi pada utas asli si penelepon.
Eric Lippert menulis seri 8-bagian tentang hal itu setahun yang lalu: Fabulous Adventures In Coding
Sunting: dan inilah Anders // build / presentasi: channel9
BTW, apakah Anda memperhatikan bahwa jika Anda membalik "// build /" terbalik, Anda mendapatkan "/ plinq //" ;-)
sumber
Jon Skeet memberikan presentasi luar biasa yang mencakup metode Async di C # 5 yang mungkin Anda anggap sangat berguna:
http://skillsmatter.com/podcast/home/async-methods
sumber