Pengendali Async di ASP.NET MVC: Keuntungan Nyata / Bagaimana Mencapai?


12

Saya telah bekerja melalui artikel tentang metode pengontrol asinkron dalam ASP.NET MVC ( http://visualstudiomagazine.com/articles/2013/07/23/async-actions-in-aspnet-mvc-4.aspx ) dan saya pikir Saya mungkin kehilangan intinya.

Pertimbangkan metode ini yang saya tulis, yang sangat mirip dengan contoh dari artikel:

[HttpGet]
[AsyncTimeout(8000)]
[HandleError(ExceptionType = typeof(TimeoutException), View = "TimedOut")]
public async Task<ActionResult> Index(CancellationToken cancellationToken)
{
    WidgetPageViewModel model = new WidgetPageViewModel()
    {
        toAdd = new Widget()
    };
    model.all = await _repo.GetAllAsync(cancellationToken);
    return View(model);
}

Seperti yang saya pahami, inilah yang akan terjadi saat runtime:

  1. Utas ASP.NET akan dibuat untuk permintaan HTTP yang masuk.

  2. Utas ini akan (setelah melakukan beberapa pekerjaan awal yang diperlukan) memasukkan metode Indeks saya () di atas.

  3. Eksekusi akan mencapai kata kunci "menunggu" dan memulai proses akuisisi data pada utas lainnya.

  4. Utas "ASP.NET" yang asli akan kembali ke kode yang disebut metode penangan saya, dengan turunan tugas kelas sebagai nilai kembali.

  5. Kode infrastruktur yang disebut metode penangan saya akan terus beroperasi pada utas "ASP.NET" yang asli, hingga mencapai titik di mana ia perlu menggunakan objek ActionResult yang sebenarnya (misalnya untuk merender halaman).

  6. Penelepon kemudian akan mengakses objek ini menggunakan anggota Task.Result, yang akan menyebabkannya (yaitu utas "ASP.NET") untuk menunggu utas yang dibuat secara implisit pada langkah # 3 di atas.

Saya tidak melihat apa yang dicapai ini dibandingkan dengan hal yang sama tanpa menunggu / async, kecuali untuk dua hal yang saya anggap remeh:

  • Utas penelepon dan utas pekerja yang dibuat oleh menunggu dapat beroperasi secara paralel untuk beberapa periode waktu (bagian "hingga" dari # 5 di atas). Firasat saya adalah bahwa periode waktu cukup kecil. Ketika infrastruktur memanggil menjadi metode pengontrol, saya pikir umumnya membutuhkan ActionResult panggilan pengontrol yang sebenarnya sebelum dapat melakukan banyak (jika ada) lebih banyak.

  • Ada beberapa infrastruktur baru yang bermanfaat terkait dengan batas waktu dan pembatalan operasi pengontrol asinkron yang sudah berjalan lama.

Tujuan menambahkan metode pengontrol async seharusnya membebaskan thread pekerja ASP.NET tersebut untuk benar-benar menjawab permintaan HTTP. Utas ini adalah sumber daya yang terbatas. Sayangnya, saya tidak melihat bagaimana pola yang disarankan dalam artikel sebenarnya berfungsi untuk melestarikan utas ini. Dan bahkan jika itu terjadi, dan entah bagaimana membebani beban penanganan permintaan ke beberapa utas non-ASP.NET, apa yang dicapai? Apakah utas yang kebetulan mampu menangani permintaan HTTP yang jauh berbeda dari utas pada umumnya?


Execution will reach the "await" keyword and kick off a data acquisition process on another thread-- Belum tentu. asynctidak memerlukan utas lainnya ... Ini merupakan kelanjutan. Itu dapat dilakukan dengan menyusun ulang instruksi pada utas yang sama.
Robert Harvey


"Eksekusi akan mencapai kata kunci yang menunggu dan memulai proses akuisisi data di utas lain." Anda mendapatkan ini mundur: menunggu adalah ketika kembali. Coba dan bagi sehingga Anda menyimpan hasilnya dari GetAllAsync () dalam sebuah variabel dan menunggu itu sebagai gantinya dan lihat apakah itu menjadi lebih jelas.
Esben Skov Pedersen

Jawaban:


9

ASP.Net yang tidak menggunakan Task Parallel Library (TPL) terbatas dalam jumlah permintaan yang dapat ditangani secara bersamaan dengan jumlah utas di kumpulan utas. ASP.Net yang menggunakan TPL dibatasi oleh CPU / memori / IO dari permintaan penanganan mesin.

Perpustakaan Tugas Paralel (TPL) tidak mengkonsumsi utas seperti yang Anda pikirkan. Tugas bukan utas, mereka adalah pembungkus di sekitar beberapa unit perhitungan. Penjadwal tugas bertanggung jawab untuk mengeksekusi setiap tugas pada utas apa pun yang tidak sibuk. Saat runtime, menunggu tugas tidak memblokir utas, itu hanya memarkir status eksekusi sehingga dapat melanjutkan di lain waktu.

Biasanya, permintaan HTTP tunggal akan ditangani oleh utas tunggal, sepenuhnya menghapus utas itu dari kolam sampai respons dikembalikan. Dengan TPL, Anda tidak terikat oleh batasan ini. Setiap permintaan yang masuk memulai kelanjutan dengan setiap unit perhitungan yang diperlukan untuk menghitung respons yang dapat dieksekusi pada utas apa pun di kumpulan. Dengan model ini, Anda dapat menangani lebih banyak permintaan bersamaan daripada dengan ASP.Net standar.


Jadi kapan thread ASP.NET dikembalikan ke kolam renang? Kapan kata kunci "tunggu" dipukul?
user1172763

async / await + TPL memungkinkan kompiler untuk membagi kode Anda menjadi unit komputasi independen yang dijalankan oleh penjadwal tugas. Utas secara konseptual dikembalikan ke kumpulan ketika penjadwal tugas tidak memiliki lagi tugas yang dapat dieksekusi dan utas menyelesaikan pekerjaan yang diberikan padanya.
mortalapeman

Ini secara konseptual benar dan mungkin jawaban yang berguna ... namun kenyataannya sedikit lebih rumit karena ketangkasan utas .
John Wu
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.