ข้อดีของการใช้ async กับ MVC5 คืออะไร?


120

อะไรคือความแตกต่างระหว่าง:

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);
}

และ:

[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);
}

ฉันเห็นว่ารหัส MVC ตอนนี้มี async แต่ความแตกต่างคืออะไร หนึ่งให้ประสิทธิภาพที่ดีกว่าอื่น ๆ หรือไม่? การแก้ปัญหากับปัญหาหนึ่งง่ายกว่าปัญหาอื่น ๆ หรือไม่? ฉันควรเปลี่ยนแปลงคอนโทรลเลอร์อื่นสำหรับแอปพลิเคชันของฉันเพื่อเพิ่ม Async หรือไม่


ในสถานการณ์ส่วนใหญ่ไม่มีประโยชน์ร้ายแรงสำหรับการใช้ async ใน MVC แต่มีข้อเสียมากมาย
Chris Marisic

1
@ChrisMarisic - หนึ่งในสิ่งที่ร้ายแรงที่สุด: คุณไม่สามารถใช้ ReaderWriterLock หรือไพรมารีซิงโครไนซ์อื่น ๆ ได้ (ยกเว้น Semaphore)
Quarkly

คำตอบ:


170

การดำเนินการ async จะมีประโยชน์เฉพาะเมื่อคุณกำลังดำเนินการเชื่อมต่อ I / O เช่นการเรียกเซิร์ฟเวอร์ระยะไกล ประโยชน์ของการเรียก async คือในระหว่างการดำเนินการ I / O จะไม่มีการใช้เธรดผู้ปฏิบัติงาน ASP.NET นี่คือวิธีการทำงานของตัวอย่างแรก:

  1. เมื่อคำขอเข้าสู่การดำเนินการ ASP.NET จะรับเธรดจากเธรดพูลและเริ่มดำเนินการ
  2. IdentityManager.Authentication.CheckPasswordAndSignInวิธีการถูกเรียก นี่คือการบล็อกการโทร -> ในระหว่างการโทรทั้งหมดเธรดผู้ปฏิบัติงานกำลังถูกคุกคาม

และนี่คือวิธีการทำงานของการโทรครั้งที่สอง:

  1. เมื่อคำขอเข้าสู่การดำเนินการ ASP.NET จะรับเธรดจากเธรดพูลและเริ่มดำเนินการ
  2. IdentityManager.Authentication.CheckPasswordAndSignInAsyncเรียกว่าซึ่งผลตอบแทนทันที มีการลงทะเบียนพอร์ตเสร็จสิ้น I / O และเธรดผู้ปฏิบัติงาน ASP.NET ถูกปล่อยไปยังเธรดพูล
  3. ต่อมาเมื่อการดำเนินการเสร็จสิ้นพอร์ต I / O Completion จะถูกส่งสัญญาณและเธรดอื่นจะถูกดึงออกจากเธรดพูลเพื่อเสร็จสิ้นการคืนมุมมอง

ดังที่คุณเห็นในกรณีที่สองเธรดผู้ปฏิบัติงาน ASP.NET ถูกใช้ในช่วงเวลาสั้น ๆ เท่านั้น ซึ่งหมายความว่ามีเธรดจำนวนมากขึ้นในพูลสำหรับให้บริการคำขออื่น ๆ

เพื่อสรุปให้ใช้ async actions ก็ต่อเมื่อคุณมี async API ที่แท้จริงอยู่ภายใน หากคุณทำการปิดกั้นการโทรภายในการดำเนินการแบบไม่ซิงค์คุณกำลังฆ่าผลประโยชน์ทั้งหมดของมัน


วิธีการซิงโครไนซ์บริบท นี่จะเป็นค่าใช้จ่ายที่คุณไม่ต้องการใช้ async actions หรือไม่? "ค่าใช้จ่ายของเมธอด async ที่ดำเนินการแบบอะซิงโครนัสจริง ๆ ขึ้นอยู่กับว่าจำเป็นต้องสลับเธรดโดยใช้ SynchronizationContext.Post หรือไม่ถ้าเป็นเช่นนั้นค่าใช้จ่ายจะถูกครอบงำโดยสวิตช์เธรดที่ดำเนินการต่อซึ่งหมายความว่า SynchronizationContext ปัจจุบันทำให้ ความแตกต่างที่ยิ่งใหญ่” (Async ใน C # 5.0, 2012, Alex Davies)
annemartijn

1
@ คุณดารินทำไมปล่อยกระทู้หลักจัง เธรด จำกัด หรือไม่
Omtechguy

1
@Omtechguy ทางออกที่ดีกว่าคือการย้ายคำขอที่ไม่ใช่ ASP.NET ไปยัง CDN CDN แบบธรรมดาเป็นเพียงการใช้โดเมนย่อยและแอพพูลแยกต่างหากสำหรับไฟล์ฟิสิคัลเช่นจาวาสคริปต์และรูปภาพของคุณ หรือคุณสามารถใช้ NgineX / Lighttpd / Apache สำหรับไฟล์หรือคุณอาจใช้บริการของบุคคลที่สามเช่น Akamai (king สำหรับ CDN แต่แพงที่สุด)
Chris Marisic

ฉันยังคงสับสน เมื่อCheckPasswordAndSignInAsyncถูกเรียก ASP.NET จะนำเธรดอื่นจากเธรดพูลและเริ่มดำเนินการใช่หรือไม่ ถ้าไม่เป็นเช่นนั้นจะchecking password procedureดำเนินการที่ใด
KevinBui

2

โดยปกติการร้องขอ HTTP เดียวจะถูกจัดการโดยเธรดเดียวโดยจะลบเธรดนั้นออกจากพูลอย่างสมบูรณ์จนกว่าจะมีการตอบกลับ ด้วย TPL คุณจะไม่ถูกผูกมัดโดยข้อ จำกัด นี้ คำขอใด ๆ ที่เข้ามาจะเริ่มต้นความต่อเนื่องกับแต่ละหน่วยการคำนวณที่จำเป็นในการคำนวณการตอบสนองที่สามารถดำเนินการกับเธรดใด ๆ ในพูล ด้วยโมเดลนี้คุณสามารถจัดการคำขอพร้อมกันได้มากกว่า ASP.Net มาตรฐาน

หากเป็นงานใหม่ที่จะเกิดขึ้นหรือไม่และควรรอหรือไม่ มักจะนึกถึง 70 ms ซึ่งเป็นค่าประมาณ สูงสุด เวลาที่ควรเรียกใช้วิธีใด ๆ หากนานกว่านั้น UI ของคุณอาจไม่ตอบสนองมากนัก


0

ในเว็บแอปพลิเคชันที่เห็นคำขอพร้อมกันจำนวนมากเมื่อเริ่มต้นระบบหรือมีการโหลดแบบไม่ต่อเนื่อง (ซึ่งการทำงานพร้อมกันเพิ่มขึ้นอย่างกะทันหัน) การเรียกใช้บริการเว็บแบบอะซิงโครนัสเหล่านี้จะเพิ่มการตอบสนองของแอปพลิเคชันของคุณ คำขอแบบอะซิงโครนัสใช้เวลาในการประมวลผลเท่ากับคำขอแบบซิงโครนัส ตัวอย่างเช่นหากคำขอเรียกใช้บริการเว็บที่ต้องใช้เวลาสองวินาทีในการดำเนินการคำขอจะใช้เวลาสองวินาทีไม่ว่าจะดำเนินการแบบซิงโครนัสหรืออะซิงโครนัส อย่างไรก็ตามในระหว่างการโทรแบบอะซิงโครนัสเธรดจะไม่ถูกบล็อกจากการตอบสนองต่อคำร้องขออื่น ๆ ในขณะที่รอให้คำร้องขอแรกเสร็จสมบูรณ์ ดังนั้นการร้องขอแบบอะซิงโครนัสจะป้องกันการจัดคิวการร้องขอและการเติบโตของเธรดพูลเมื่อมีการร้องขอพร้อมกันจำนวนมากที่เรียกใช้การดำเนินการที่รันเป็นเวลานาน


หากแอปพลิเคชัน aspnet ของคุณส่วนใหญ่ประกอบด้วยการโทรไปยังเว็บเซิร์ฟเวอร์อื่น ๆ คุณส่วนใหญ่จะทำงานเป็น 'เกตเวย์' / 'พร็อกซี' และ async มีประโยชน์สำหรับจุดประสงค์นั้น
Chris Marisic
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.