Apa keuntungan menggunakan async dengan MVC5?


120

Apa perbedaan antara:

public ActionResult Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        IdentityResult result = IdentityManager.Authentication.CheckPasswordAndSignIn(AuthenticationManager, model.UserName, model.Password, model.RememberMe);
        if (result.Success)
        {
            return Redirect("~/home");
        }
        else
        {
            AddErrors(result);
        }
    }
    return View(model);
}

dan:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        IdentityResult result = await IdentityManager.Authentication.CheckPasswordAndSignInAsync(AuthenticationManager, model.UserName, model.Password, model.RememberMe);
        if (result.Success)
        {
            return Redirect("~/home");
        }
        else
        {
            AddErrors(result);
        }
    }
    return View(model);
}

Saya melihat bahwa kode MVC sekarang memiliki async tetapi apa bedanya. Apakah yang satu memberikan kinerja yang jauh lebih baik daripada yang lain? Apakah lebih mudah untuk men-debug masalah dengan salah satu dari yang lain? Haruskah saya membuat perubahan pada pengontrol lain untuk aplikasi saya untuk menambahkan Async?


Dalam sebagian besar situasi, tidak ada manfaat serius untuk menggunakan asinkron di MVC, namun ada banyak hal negatif
Chris Marisic

1
@ChrisMarisic - Salah satu yang paling serius: Anda tidak dapat menggunakan ReaderWriterLock atau primitif sinkronisasi lainnya (kecuali untuk Semaphore).
Quarkly

Jawaban:


170

Tindakan async hanya berguna ketika Anda menjalankan operasi terikat I / O seperti panggilan server jarak jauh. Manfaat dari panggilan async adalah bahwa selama operasi I / O, tidak ada thread pekerja ASP.NET yang sedang digunakan. Jadi, inilah cara kerja contoh pertama:

  1. Ketika permintaan mengenai tindakan, ASP.NET mengambil utas dari kumpulan utas dan mulai menjalankannya.
  2. The IdentityManager.Authentication.CheckPasswordAndSignInMetode dipanggil. Ini adalah panggilan pemblokiran -> selama seluruh panggilan, utas pekerja terancam.

Dan inilah cara kerja panggilan kedua:

  1. Ketika permintaan mengenai tindakan, ASP.NET mengambil utas dari kumpulan utas dan mulai menjalankannya.
  2. The IdentityManager.Authentication.CheckPasswordAndSignInAsyncdisebut yang mengembalikan segera. Port penyelesaian I / O terdaftar dan utas pekerja ASP.NET diluncurkan ke kumpulan utas.
  3. Nanti saat operasi selesai, port Penyelesaian I / O diberi tanda, utas lain ditarik dari kumpulan utas untuk menyelesaikan mengembalikan tampilan.

Seperti yang Anda lihat dalam kasus kedua thread pekerja ASP.NET hanya digunakan untuk waktu yang singkat. Ini berarti ada lebih banyak utas yang tersedia di kumpulan untuk melayani permintaan lain.

Jadi untuk menyimpulkan, gunakan tindakan asinkron hanya jika Anda memiliki API asinkron yang sebenarnya di dalamnya. Jika Anda membuat panggilan pemblokiran di dalam tindakan asinkron, Anda mematikan seluruh manfaatnya.


Bagaimana dengan sinkronisasi konteks. Tidakkah ini akan menjadi overhead sehingga Anda tidak ingin menggunakan tindakan asinkron sama sekali? "Overhead metode async yang benar-benar dijalankan secara asinkron bergantung sepenuhnya pada apakah ia perlu mengganti thread menggunakan SynchronizationContext.Post. Jika demikian, overhead didominasi oleh switch thread yang dijalankannya saat melanjutkan. Itu berarti SynchronizationContext saat ini membuat perbedaan besar. " (Asinkron di C # 5.0, 2012, Alex Davies)
annemartijn

1
@Darin Mengapa begitu penting untuk merilis utas utama? Apakah utas dibatasi?
Omtechguy

1
@Omtechguy solusi yang lebih baik adalah dengan memindahkan permintaan non ASP.NET ke CDN. CDN sederhana hanya menggunakan subdomain dan kumpulan aplikasi terpisah untuk file fisik seperti javascript dan gambar Anda. Atau Anda dapat menggunakan NgineX / Lighttpd / Apache untuk file, atau Anda dapat menggunakan layanan pihak ketiga seperti Akamai (raja untuk CDN tetapi paling mahal)
Chris Marisic

Saya masih bingung. Ketika CheckPasswordAndSignInAsyncdipanggil, ASP.NET mengambil utas lain dari kumpulan utas dan mulai menjalankannya, bukan? Jika tidak, di mana akan checking password proceduredieksekusi?
KevinBui

2

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

Jika itu adalah tugas baru yang akan muncul, atau tidak, dan apakah itu harus ditunggu atau tidak. Selalu pikirkan tentang 70 ms itu, yaitu kira-kira. maks. waktu yang dibutuhkan oleh panggilan metode apa pun. Jika lebih panjang, maka UI Anda kemungkinan besar tidak akan terasa sangat responsif.


0

Dalam aplikasi web yang melihat sejumlah besar permintaan bersamaan saat start-up atau memiliki beban bursty (di mana konkurensi meningkat secara tiba-tiba), membuat panggilan layanan web ini asinkron akan meningkatkan daya tanggap aplikasi Anda. Permintaan asinkron membutuhkan jumlah waktu yang sama untuk diproses sebagai permintaan sinkron. Misalnya, jika permintaan membuat panggilan layanan web yang membutuhkan waktu dua detik untuk menyelesaikannya, permintaan tersebut memerlukan waktu dua detik baik itu dilakukan secara sinkron maupun asinkron. Namun, selama panggilan asynchronous, sebuah thread tidak diblokir untuk menanggapi permintaan lain saat menunggu permintaan pertama selesai. Oleh karena itu, permintaan asinkron mencegah antrian permintaan dan pertumbuhan kumpulan thread saat ada banyak permintaan serentak yang meminta operasi yang berjalan lama.


Jika aplikasi aspnet Anda sebagian besar terdiri dari panggilan ke server web lain, Anda sebagian besar berperilaku sebagai 'gateway' / 'proxy' dan async berguna untuk tujuan itu.
Chris Marisic
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.