Dari pemahaman saya salah satu hal utama yang async
danawait
lakukan adalah untuk membuat kode mudah untuk menulis dan membaca - tetapi menggunakan mereka sama untuk pemijahan benang latar belakang untuk melakukan logika durasi panjang?
Saat ini saya sedang mencoba contoh paling dasar. Saya telah menambahkan beberapa komentar sebaris. Bisakah Anda menjelaskannya untuk saya?
// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
Task<int> access = DoSomethingAsync();
// task independent stuff here
// this line is reached after the 5 seconds sleep from
// DoSomethingAsync() method. Shouldn't it be reached immediately?
int a = 1;
// from my understanding the waiting should be done here.
int x = await access;
}
async Task<int> DoSomethingAsync()
{
// is this executed on a background thread?
System.Threading.Thread.Sleep(5000);
return 1;
}
c#
.net
asynchronous
async-await
Dan Dinu
sumber
sumber
Jawaban:
Saat menggunakan
async
danawait
kompiler menghasilkan mesin status di latar belakang.Berikut adalah contoh yang saya harap saya bisa menjelaskan beberapa detail tingkat tinggi yang sedang terjadi:
Oke, jadi apa yang terjadi di sini:
Task<int> longRunningTask = LongRunningOperationAsync();
mulai mengeksekusiLongRunningOperation
Pekerjaan independen dilakukan pada mari kita asumsikan Utas Utama (Utas ID = 1) kemudian
await longRunningTask
tercapai.Sekarang, jika
longRunningTask
belum selesai dan masih berjalan,MyMethodAsync()
akan kembali ke metode pemanggilannya, sehingga utas utama tidak diblokir. KetikalongRunningTask
selesai maka utas dari ThreadPool (dapat berupa utas apa pun) akan kembali keMyMethodAsync()
dalam konteks sebelumnya dan melanjutkan eksekusi (dalam hal ini mencetak hasilnya ke konsol).Kasus kedua adalah bahwa
longRunningTask
telah menyelesaikan eksekusi dan hasilnya tersedia. Ketika mencapaiawait longRunningTask
kita sudah memiliki hasil sehingga kode akan terus dieksekusi pada utas yang sama. (dalam hal ini hasil cetak ke konsol). Tentu saja ini bukan kasus untuk contoh di atas, di mana ada yangTask.Delay(1000)
terlibat.sumber
Mereka membuat kode asinkron mudah ditulis dan dibaca, ya.
Tidak semuanya.
Kata
async
kunci memungkinkanawait
kata kunci. Jadi metode apa pun yang digunakanawait
harus ditandaiasync
.Tidak, karena
async
metode tidak dijalankan pada utas lainnya secara default.Tidak.
Anda mungkin menemukan
async
/await
intro saya bermanfaat. Dokumen resmi MSDN juga luar biasa baik (khususnya bagian TAP ), danasync
tim mengeluarkan FAQ yang sangat baik .sumber
async
metode tidak dijalankan pada utas lainnya secara default. Dalam contoh Anda,Sleep()
panggilan di dalamDoSomethingAsync()
memblokir utas saat ini yang mencegah eksekusi dari melanjutkanbutton1_Click()
hinggaDoSomethingAsync()
selesai. Perhatikan bahwa saatThread.Sleep()
memblokir utas pelaksana,Task.Delay() does not.
Penjelasan
Berikut ini adalah contoh cepat dari
async
/await
di tingkat tinggi. Ada lebih banyak detail untuk dipertimbangkan di luar ini.Catatan:
Task.Delay(1000)
disimulasikan melakukan pekerjaan selama 1 detik. Saya pikir yang terbaik adalah memikirkan ini sebagai menunggu tanggapan dari sumber eksternal. Karena kode kami menunggu respons, sistem dapat mengatur tugas yang sedang berjalan ke samping dan kembali ke sana setelah selesai. Sementara itu, ia dapat melakukan beberapa pekerjaan lain pada utas itu.Pada contoh di bawah ini, blok pertama melakukan hal itu. Ini memulai semua tugas segera (
Task.Delay
garis) dan menetapkannya ke samping. Kode akan berhenti diawait a
baris sampai penundaan 1 detik dilakukan sebelum pergi ke baris berikutnya. Sejakb
,c
,d
, dane
semua mulai melaksanakan pada waktu yang hampir sama persis sepertia
(karena kurangnya menunggu), mereka harus menyelesaikan di sekitar waktu yang sama dalam hal ini.Dalam contoh di bawah ini, blok kedua memulai tugas dan menunggu sampai selesai (itulah yang
await
dilakukan) sebelum memulai tugas berikutnya. Setiap iterasi ini membutuhkan waktu 1 detik. Iniawait
sedang menjeda program dan menunggu hasilnya sebelum melanjutkan. Ini adalah perbedaan utama antara blok pertama dan kedua.Contoh
KELUARAN:
Info tambahan tentang SynchronizationContext
Catatan: Di sinilah segalanya menjadi sedikit berkabut bagi saya, jadi jika saya salah dalam hal apa pun, perbaiki saya dan saya akan memperbarui jawabannya. Sangat penting untuk memiliki pemahaman dasar tentang bagaimana ini bekerja tetapi Anda bisa bertahan tanpa menjadi ahli selama Anda tidak pernah menggunakannya
ConfigureAwait(false)
, meskipun Anda mungkin akan kehilangan beberapa peluang untuk optimasi, saya berasumsi.Ada satu aspek ini yang membuat
async
/await
konsep yang agak rumit untuk dipahami. Itulah fakta bahwa dalam contoh ini, ini semua terjadi pada utas yang sama (atau setidaknya yang tampaknya merupakan utas yang sama terkait dengan utasnyaSynchronizationContext
). Secara default,await
akan mengembalikan konteks sinkronisasi dari utas asli yang sedang berjalan. Misalnya, di ASP.NET Anda memilikiHttpContext
yang terkait dengan utas saat permintaan masuk. Konteks ini berisi hal-hal khusus untuk permintaan Http asli seperti objek Permintaan asli yang memiliki hal-hal seperti bahasa, alamat IP, header, dll. Jika Anda mengganti utas saat memproses sesuatu, Anda mungkin berpotensi mencoba menarik informasi dari objek ini pada objek lainHttpContext
yang bisa menjadi bencana. Jika Anda tahu Anda tidak akan menggunakan konteks untuk apa pun, Anda dapat memilih untuk "tidak peduli" tentang hal itu. Ini pada dasarnya memungkinkan kode Anda dijalankan pada utas terpisah tanpa membawa konteksnya.Bagaimana Anda mencapai ini? Secara default,
await a;
kode sebenarnya membuat asumsi bahwa Anda DO ingin menangkap dan memulihkan konteks:Jika Anda ingin memperbolehkan kode utama untuk melanjutkan pada utas baru tanpa konteks asli, Anda cukup menggunakan false dan bukan true sehingga ia tahu itu tidak perlu mengembalikan konteks.
Setelah program dihentikan sementara, program akan terus berpotensi pada utas yang sama sekali berbeda dengan konteks yang berbeda. Di sinilah peningkatan kinerja akan berasal - ini dapat berlanjut pada utas yang tersedia tanpa harus mengembalikan konteks aslinya.
Apakah ini membingungkan? Tentu saja! Bisakah Anda mencari tahu? Mungkin! Setelah Anda memiliki pemahaman konsep, kemudian beralih ke penjelasan Stephen Cleary yang cenderung lebih diarahkan pada seseorang dengan pemahaman teknis tentang
async
/await
sudah.sumber
await MethodCall()
apakah benar-benar pemborosan? Anda mungkin juga menjatuhkanawait
/async
?await
, saya pikir itu melepaskan utas kembali ke kolam daripada menahannya. Ini membuatnya tersedia untuk digunakan di tempat lain sambil menunggu kembalinya TugasLebih jauh ke jawaban lain, lihat menunggu (C # Referensi)
dan lebih khusus pada contoh yang disertakan, ini menjelaskan situasi Anda sedikit
sumber
Task.Delay
api.Menampilkan penjelasan di atas dalam aksi dalam program konsol sederhana:
Dan hasilnya adalah:
Jadi,
TestAsyncAwaitMethods
. Itu segera kembali tanpa menghentikan utas saat ini dan kami segera melihat pesan 'Tekan sembarang tombol untuk keluar'LongRunningMethod
berjalan di latar belakang. Setelah selesai, utas lain dari Threadpool mengambil konteks ini dan menampilkan pesan terakhirJadi, bukan utas yang diblokir.
sumber
return 1
bagian ini layak mendapatkan beberapa penjelasan lebih lanjut:await
kata kunci memungkinkan Anda untuk mengembalikan jenis yang mendasarinyaTask<T>
secara langsung, sehingga memudahkan untuk menyesuaikan kode Anda yang ada dengan dunia menunggu / async . Tetapi Anda tidak harus mengembalikan nilai, karena dimungkinkan untuk mengembalikanTask
tanpa menentukan jenis pengembalian, yang akan setara denganvoid
metode sinkron . Ingatlah bahwa C # memungkinkanasync void
metode, tetapi Anda harus menghindari melakukannya kecuali jika Anda menangani penangan acara.Saya pikir Anda telah mengambil contoh yang buruk dengan
System.Threading.Thread.Sleep
Titik
async
Tugas adalah membiarkannya dieksekusi di latar belakang tanpa mengunci utas utama, seperti melakukan aDownloadFileAsync
System.Threading.Thread.Sleep
bukan sesuatu yang "sedang dikerjakan", itu hanya tidur, dan karena itu baris Anda berikutnya tercapai setelah 5 detik ...Baca artikel ini, saya pikir ini adalah penjelasan
async
danawait
konsep yang hebat: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspxsumber
Thread.Sleep
memblokir utas (utas tidak dapat melakukan hal lain selain duduk diam), tetapi metode async tidak. Dalam hal iniDownloadFileAsync
, utas dapat pergi dan melakukan sesuatu yang lain sampai balasan datang dari server jauh. Tempat penampung yang lebih baik untuk "beberapa tugas yang membutuhkan waktu" dalam metode async adalahTask.Delay
, karena itu sebenarnya asinkron.async
kata kunci. Tetapi metodenya masih berjalan secara sinkron, dan jawaban ini menjelaskan mengapa: karena dia tidak benar-benar menjalankan kode asinkron. Metode yang ditandaiasync
masih berjalan secara sinkron hingga Andaawait
tidak lengkapTask
. Jika tidak adaawait
, maka metode berjalan secara sinkron, dan kompiler akan memperingatkan Anda tentang hal itu.Berikut adalah program konsol cepat untuk menjelaskannya kepada mereka yang mengikuti. The
TaskToDo
metode adalah metode berjalan lama Anda bahwa Anda ingin membuat async. Menjalankan async dilakukan denganTestAsync
metode ini. Metode loop tes hanya menjalankanTaskToDo
tugas dan menjalankannya async. Anda dapat melihat bahwa di hasil karena mereka tidak menyelesaikan dalam urutan yang sama dari menjalankan ke menjalankan - mereka melaporkan ke utas UI konsol ketika mereka selesai. Sederhana, tapi saya pikir contoh sederhana menunjukkan inti dari pola lebih baik daripada contoh yang lebih terlibat:sumber
Untuk pembelajaran tercepat ..
Memahami aliran eksekusi metode (dengan diagram): 3 menit
Introspeksi pertanyaan (sake pembelajaran): 1 menit
Cepat melewati sintaks gula: 5 menit
Bagikan kebingungan pengembang: 5 menit
Masalah: Cepat ubah implementasi kode normal dunia nyata menjadi kode Async: 2 menit
Kemana Selanjutnya?
Memahami aliran eksekusi metode (dengan diagram): 3 menit
Dalam gambar ini, fokus saja pada # 6 (tidak lebih)
Pada langkah # 6: Eksekusi berhenti di sini karena kehabisan pekerjaan. Untuk melanjutkannya, dibutuhkan hasil dari getStringTask (semacam fungsi). Oleh karena itu, ia menggunakan
await
operator untuk menunda progresnya dan memberikan kendali kembali (hasil) kepada penelepon (dari metode yang kita gunakan ini). Panggilan sebenarnya ke getStringTask dibuat lebih awal di # 2. Di # 2 janji dibuat untuk mengembalikan hasil string. Tetapi kapan akan mengembalikan hasilnya? Haruskah kita (# 1: AccessTheWebAsync) melakukan panggilan kedua lagi? Siapa yang mendapatkan hasilnya, # 2 (pernyataan panggilan) atau # 6 (menunggu pernyataan)Penelepon eksternal AccessTheWebAsync () juga sedang menunggu sekarang. Jadi pemanggil menunggu AccessTheWebAsync, dan AccessTheWebAsync sedang menunggu GetStringAsync saat ini. Yang menarik adalah AccessTheWebAsync melakukan beberapa pekerjaan sebelum menunggu (# 4) mungkin untuk menghemat waktu dari menunggu. Kebebasan yang sama untuk multitask juga tersedia untuk penelepon eksternal (dan semua penelepon dalam rantai) dan ini adalah nilai tambah terbesar dari hal 'async' ini! Anda merasa itu sinkron..atau normal tetapi tidak.
Ingat, metode itu sudah dikembalikan (# 2), tidak bisa kembali lagi (tidak ada kedua kalinya). Jadi bagaimana penelepon tahu? Ini semua tentang Tugas! Tugas telah berlalu. Tugas menunggu (bukan metode, bukan nilai). Nilai akan ditetapkan dalam Tugas. Status tugas akan ditetapkan untuk selesai. Pemanggil hanya memonitor Tugas (# 6). Jadi 6 # adalah jawaban ke mana / siapa yang mendapatkan hasilnya. Bacaan selanjutnya untuk nanti di sini .
Introspeksi pertanyaan demi pembelajaran: 1 menit
Mari kita sesuaikan pertanyaannya sedikit:
Karena belajar
Task
secara otomatis mencakup dua lainnya (dan menjawab pertanyaan Anda)Cepat melewati sintaks gula: 5 menit
Sebelum konversi (metode asli)
internal static int Method(int arg0, int arg1) { int result = arg0 + arg1; IO(); // Do some long running IO. return result; }
metode Task-ified untuk memanggil metode di atas
internal static Task<int> MethodTask(int arg0, int arg1) { Task<int> task = new Task<int>(() => Method(arg0, arg1)); task.Start(); // Hot task (started task) should always be returned. return task; }
Apakah kami menyebutkan menunggu atau async? Tidak. Hubungi metode di atas dan Anda mendapatkan tugas yang dapat Anda pantau. Anda sudah tahu tugas apa yang dikembalikan .. integer.
Memanggil Tugas sedikit rumit dan saat itulah kata kunci mulai muncul. Mari kita panggil MethodTask ()
internal static async Task<int> MethodAsync(int arg0, int arg1) { int result = await HelperMethods.MethodTask(arg0, arg1); return result; }
Kode yang sama di atas ditambahkan sebagai gambar di bawah ini:
await
async
(sintaksis wajib)Async
sebagai awalan (standar pengkodean)await
mudah dimengerti tetapi dua sisanya (async
,Async
) mungkin tidak :). Yah, itu seharusnya lebih masuk akal untuk kompiler sekalipun. Selanjutnya dibaca nanti di siniBagikan kebingungan pengembang: 5 menit
Pengembang telah membuat kesalahan dengan tidak mengimplementasikan
Task
tetapi masih berfungsi! Cobalah untuk memahami pertanyaan dan hanya jawaban yang diterima yang disediakan di sini . Semoga Anda telah membaca dan sepenuhnya dipahami. Ringkasannya adalah bahwa kita mungkin tidak melihat / mengimplementasikan 'Tugas' tetapi dilaksanakan di suatu tempat di kelas induk. Demikian juga dalam contoh kita memanggil yang sudah dibangunMethodAsync()
jauh lebih mudah daripada menerapkan metode itu denganTask
(MethodTask()
) diri kita sendiri. Sebagian besar pengembang merasa kesulitan untukTasks
mengubah kode sambil mengonversi kode ke kode Asynchronous.Kiat: Cobalah untuk menemukan implementasi Async yang ada (seperti
MethodAsync
atauToListAsync
) untuk melakukan outsourcing kesulitan. Jadi kita hanya perlu berurusan dengan Async dan menunggu (yang mudah dan sangat mirip dengan kode normal)Masalah: Cepat ubah implementasi kode normal dunia nyata ke operasi Async: 2 menit
Baris kode yang ditunjukkan di bawah ini di Lapisan Data mulai rusak (banyak tempat). Karena kami memperbarui beberapa kode kami dari .Net framework 4.2. * Ke .Net core. Kami harus memperbaikinya dalam 1 jam di seluruh aplikasi!
mudah!
Async
danawait
dalam.saluran kode panggilan diubah seperti ini
Metode tanda tangan berubah dari
Contract GetContract(int contractnumber)
untuk
async Task<Contract> GetContractAsync(int contractnumber)
Metode panggilan juga terpengaruh:
GetContractAsync(123456);
dipanggil sebagaiGetContractAsync(123456).Result;
Kami mengubahnya di mana-mana dalam 30 menit!
Tetapi arsitek mengatakan kepada kami untuk tidak menggunakan perpustakaan EntityFramework hanya untuk ini! Ups! drama! Kemudian kami membuat implementasi Tugas kustom (yuk). Yang kamu tahu caranya. Masih mudah! .. masih yuk ..
Kemana Selanjutnya? Ada video cepat yang luar biasa yang bisa kita tonton tentang Konversi Panggilan Sinkron ke Asinkron di ASP.Net Core , mungkin itu kemungkinan arah yang akan dituju setelah membaca ini.
sumber
Semua jawaban di sini menggunakan
Task.Delay()
atauasync
fungsi bawaan lainnya. Tapi di sini adalah contoh saya yang tidak menggunakanasync
fungsi - fungsi tersebut:sumber
task.Wait();
dan bagaimana ini dapat digunakan untuk menghindari async / menunggu neraka: PJawaban ini bertujuan untuk memberikan beberapa info khusus untuk ASP.NET.
Dengan memanfaatkan async / menunggu di pengontrol MVC, dimungkinkan untuk meningkatkan pemanfaatan kumpulan benang dan mencapai throughput yang jauh lebih baik, seperti yang dijelaskan dalam artikel di bawah ini,
http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4
sumber
Async & Menunggu Penjelasan Sederhana
Analogi Sederhana
Seseorang mungkin menunggu kereta pagi mereka. Ini semua mereka lakukan karena ini adalah tugas utama mereka yang sedang mereka lakukan. (pemrograman sinkron (apa yang biasanya Anda lakukan!))
Orang lain mungkin menunggu kereta pagi mereka sementara mereka merokok dan minum kopi. (Pemrograman asinkron)
Apa itu pemrograman asinkron?
Pemrograman asinkron adalah di mana seorang programmer akan memilih untuk menjalankan beberapa kodenya pada utas terpisah dari utas utama eksekusi dan kemudian memberi tahu utas utama pada penyelesaiannya.
Apa yang sebenarnya dilakukan kata kunci async?
Awalan kata kunci async ke nama metode seperti
memungkinkan pemrogram untuk menggunakan kata kunci yang menunggu saat memanggil tugas yang tidak sinkron. Hanya itu yang dilakukannya.
Mengapa ini penting?
Dalam banyak sistem perangkat lunak utas utama dicadangkan untuk operasi yang secara khusus berkaitan dengan Antarmuka Pengguna. Jika saya menjalankan algoritme rekursif yang sangat kompleks yang membutuhkan waktu 5 detik untuk menyelesaikannya di komputer saya, tetapi saya menjalankan ini pada Utas Utama (utas UI) Saat pengguna mencoba mengklik apa pun pada aplikasi saya, itu akan tampak membeku sebagai utas utama saya telah mengantri dan saat ini memproses terlalu banyak operasi. Akibatnya utas utama tidak dapat memproses klik mouse untuk menjalankan metode dari klik tombol.
Kapan Anda menggunakan Async dan Await?
Gunakan kata kunci asinkron secara ideal ketika Anda melakukan sesuatu yang tidak melibatkan antarmuka pengguna.
Jadi katakanlah Anda sedang menulis sebuah program yang memungkinkan pengguna membuat sketsa di ponsel mereka, tetapi setiap 5 detik akan memeriksa cuaca di internet.
Kita harus menunggu panggilan panggilan polling setiap 5 detik ke jaringan untuk mendapatkan cuaca karena pengguna aplikasi harus terus berinteraksi dengan layar sentuh seluler untuk menggambar gambar-gambar cantik.
Bagaimana Anda menggunakan Async dan Menunggu
Berikut dari contoh di atas, berikut adalah beberapa kode pseudo cara menulisnya:
Catatan Tambahan - Perbarui
Saya lupa menyebutkan dalam catatan asli saya bahwa dalam C # Anda hanya bisa menunggu metode yang dibungkus dalam Tugas. misalnya Anda dapat menunggu metode ini:
Anda tidak dapat menunggu metode yang bukan tugas seperti ini:
Jangan ragu untuk meninjau kode sumber untuk kelas Tugas di sini .
sumber
Async / Menunggu
Sebenarnya Async / Menunggu adalah sepasang kata kunci yang hanya gula sintaksis untuk membuat panggilan balik dari tugas asinkron.
Ambil contoh operasi ini:
Kode di atas memiliki beberapa kelemahan. Kesalahan tidak diteruskan dan sulit dibaca. Tetapi Async dan Await datang untuk membantu kami:
Menunggu panggilan harus menggunakan metode Async. Ini memiliki beberapa keunggulan:
CATATAN : Async dan Await digunakan dengan panggilan asinkron untuk tidak melakukan ini. Anda harus menggunakan Libary Tugas untuk ini, seperti Task.Run ().
Berikut ini adalah perbandingan antara menunggu dan tidak menunggu solusi
Ini bukan solusi async:
Ini adalah metode async:
Anda sebenarnya dapat memanggil metode async tanpa menunggu kata kunci tetapi ini berarti bahwa Pengecualian apa pun di sini tertelan dalam mode rilis:
Async dan Await tidak dimaksudkan untuk komputasi paralel. Mereka digunakan untuk tidak memblokir utas utama Anda. Ketika itu tentang asp.net atau aplikasi Windows, memblokir utas Anda karena panggilan jaringan adalah hal yang buruk. Jika Anda melakukan ini, aplikasi Anda akan menjadi tidak responsif atau bahkan macet.
Lihat ms docs untuk lebih banyak contoh.
sumber
Sejujurnya saya masih berpikir penjelasan terbaik adalah tentang masa depan dan janji di Wikipedia: http://en.wikipedia.org/wiki/Futures_and_promises
Ide dasarnya adalah bahwa Anda memiliki kumpulan utas terpisah yang menjalankan tugas secara tidak sinkron. Saat menggunakannya. Namun objek tersebut membuat janji bahwa ia akan menjalankan operasi pada suatu waktu dan memberikan Anda hasilnya ketika Anda memintanya. Ini berarti bahwa itu akan memblokir ketika Anda meminta hasil dan belum selesai, tetapi jalankan di kolam utas sebaliknya.
Dari sana Anda dapat mengoptimalkan hal-hal: beberapa operasi dapat diimplementasikan async dan Anda dapat mengoptimalkan hal-hal seperti file IO dan komunikasi jaringan dengan mengelompokkan bersama permintaan berikutnya dan / atau menyusun ulang mereka. Saya tidak yakin apakah ini sudah ada dalam kerangka tugas Microsoft - tetapi jika tidak, itu akan menjadi salah satu hal pertama yang akan saya tambahkan.
Anda benar-benar dapat menerapkan pola sort-of masa depan dengan hasil dalam C # 4.0. Jika Anda ingin tahu cara kerjanya tepatnya, saya dapat merekomendasikan tautan ini yang melakukan pekerjaan yang layak: http://code.google.com/p/fracture/source/browse/trunk/Squared/TaskLib/ . Namun, jika Anda mulai mempermainkannya sendiri, Anda akan melihat bahwa Anda benar-benar membutuhkan dukungan bahasa jika Anda ingin melakukan semua hal keren - yang persis seperti yang dilakukan Microsoft.
sumber
Lihat biola ini https://dotnetfiddle.net/VhZdLU (dan tingkatkan jika memungkinkan) untuk menjalankan aplikasi konsol sederhana yang menunjukkan penggunaan Tugas, Tugas. Tunggu Semua (), asinkron, dan tunggu operator dalam program yang sama.
Biola ini akan menghapus konsep siklus eksekusi Anda.
Ini kode contohnya
Jejak yang berasal dari Output Window:
sumber
sumber
Di tingkat yang lebih tinggi:
1) Kata kunci Async memungkinkan menunggu dan hanya itu yang dilakukannya. Kata kunci Async tidak menjalankan metode dalam utas terpisah. Metode f async awal berjalan secara sinkron hingga hits menunggu tugas yang memakan waktu.
2) Anda bisa menunggu pada metode yang mengembalikan tugas atau tugas tipe T. Anda tidak bisa menunggu pada metode batal async.
3) Saat utas utama bertemu menunggu tugas yang memakan waktu atau ketika pekerjaan sebenarnya dimulai, utas utama kembali ke pemanggil metode saat ini.
4) Jika utas utama melihat menunggu pada tugas yang masih dieksekusi, itu tidak menunggu dan kembali ke pemanggil metode saat ini. Dengan cara ini, aplikasi tetap responsif.
5) Menunggu pada tugas pemrosesan, sekarang akan dijalankan pada utas terpisah dari kumpulan utas.
6) Ketika tugas menunggu ini selesai, semua kode di bawah ini akan dieksekusi oleh utas terpisah
Di bawah ini adalah kode sampel. Jalankan dan periksa id utas
sumber
Cara saya mengerti juga, harus ada jabatan ketiga ditambahkan ke dalam campuran:
Task
.Async
hanyalah kualifikasi yang Anda masukkan pada metode Anda untuk mengatakan itu adalah metode asinkron.Task
adalah kembalinyaasync
fungsi. Ini dijalankan secara tidak sinkron.Anda
await
seorang Tugas. Ketika eksekusi kode mencapai garis ini, kontrol melompat kembali ke pemanggil fungsi asli Anda di sekitarnya.Jika sebaliknya, Anda menetapkan kembalinya sebuah
async
fungsi (yaituTask
) ke variabel, ketika eksekusi kode mencapai garis ini, itu hanya terus melewati garis yang dalam fungsi sekitarnya sementara yangTask
mengeksekusi asynchronous.sumber
Artikel ini MDSN: Pemrograman Asinkron dengan async dan menunggu (C #) menjelaskannya secara eksplisit:
sumber
Dalam kode berikut ini, metode HttpClient GetByteArrayAsync mengembalikan Tugas, getContentsTask. Tugas adalah janji untuk menghasilkan array byte yang sebenarnya ketika tugas selesai. Operator yang menunggu diterapkan untuk getContentsTask untuk menunda eksekusi di SumPageSizesAsync sampai getContentsTask selesai. Sementara itu, kontrol dikembalikan ke penelepon SumPageSizesAsync. Ketika getContentsTask selesai, ekspresi menunggu mengevaluasi ke array byte.
sumber
Di bawah ini adalah kode yang membaca file excel dengan membuka dialog dan kemudian menggunakan async dan menunggu untuk menjalankan asinkron kode yang membaca satu per satu baris dari excel dan mengikat ke grid
sumber
Jawaban di sini bermanfaat sebagai pedoman umum tentang await / async. Mereka juga berisi beberapa detail tentang bagaimana kabel menunggu / async. Saya ingin berbagi pengalaman praktis dengan Anda yang harus Anda ketahui sebelum menggunakan pola desain ini.
Istilah "menunggu" adalah literal, jadi utas apa pun yang Anda panggil akan menunggu hasil metode sebelum melanjutkan. Di latar depan , ini adalah bencana . Utas latar depan memikul beban untuk membangun aplikasi Anda, termasuk tampilan, model tampilan, animasi awal, dan apa pun yang Anda miliki. Jadi ketika Anda menunggu utas latar depan, Anda menghentikan aplikasi. Pengguna menunggu dan menunggu ketika tidak ada yang tampak terjadi. Ini memberikan pengalaman pengguna yang negatif.
Anda tentu bisa menunggu utas latar menggunakan berbagai cara:
Kode lengkap untuk komentar ini ada di https://github.com/marcusts/xamarin-forms-annoyances . Lihat solusi yang disebut AwaitAsyncAntipattern.sln.
Situs GitHub juga menyediakan tautan ke diskusi yang lebih rinci tentang topik ini.
sumber
async / await
adalah sintaksis gula untuk callback, itu tidak ada hubungannya dengan threading. msdn.microsoft.com/en-us/magazine/hh456401.aspx Ini untuk kode terikat non-CPU, misalnya menunggu input atau penundaan.Task.Run
seharusnya hanya digunakan untuk kode yang terikat CPU blog.stephencleary.com/2013/10/…The term "await" is literal, so whatever thread you call it on will wait for the result of the method before continuing.
Ini tidak benar - mungkin maksud Anda Task.Wait ()? Ketika Anda menggunakanawait
, itu menetapkan sisa metode sebagai kelanjutan yang akan dieksekusi ketika apa pun yang Anda tunggu-ed selesai. Itu keluar dari metode yang Anda gunakan, sehingga penelepon dapat melanjutkan. Kemudian ketika baris yang ditunggu-tunggu benar-benar selesai, ia menyelesaikan sisa metode itu pada beberapa utas (biasanya utas pekerja).async/await
adalah tentang membebaskan .NET Threads. Saat Andaawait
menjalankan operasi yang benar-benar-async (seperti File.WriteAsync .NET), itu menangguhkan sisa metode yang Anda gunakanawait
, sehingga penelepon dapat melanjutkan dan berpotensi menyelesaikan tujuannya. Tidak ada pemblokiran thread atau menungguawait
operasi -ed. Ketika operasi yang Andaawait
selesaikan selesai, sisaasync/await
metode ini diletakkan di utas dan dieksekusi (mirip dengan ide panggilan balik).