asp.net mvc עובד בצורה מקבילית. מקבל מס’ בקשות מהclient ומשחרר thread לכל בקשה , אך הוא מוגבל למס’ הthreds הקיימים ב thread pool.

    מה שקורה הוא שלפעמים מגיעה בקשה חדשה,(במיוחד באתרים גדולים) ויש  שימוש בכל הthreads ואז נוצר תור של בקשות שממתינות

    עד שיתפנה thread.

    לעיתים (לרוב), הבקשות מתעכבות עקב פעולות חיצוניות לדוג’ קריאה מAction מסוים לApi או לdb ובינתיים ה controller מחכה לתשובה ממנו

    יוצא שאני מבזבזת זמן (ו thread) ובינתיים אני יוצרת תור של בקשות  שממתינות…

    ה -Asynchronous Controllers מאפשר לנו במקרים כאלה לשחרר את ה thread,  ז”א במקרה והגעתי ל Action שמפעיל פונקציה חיצונית הוא משחרר את הthread

    כל זמן שהaction מחכה לתשובה ובינתיים הוא מבצע פניות אחרות.

    חשוב להדגיש – הaction יקח אותו זמן , אך מהירות המערכת כולה תיגדל עקב מניעת התור.

    וזה הצורה לכתוב את זה:

    Code Snippet
    public class ContactController : Controller
        {
            private readonly IContactRepository _contactRepository;

            public ContactController()
            {
                _contactRepository = new ContactRepository();
            }

            //
            // GET: /Contact/
            [HttpGet]
            [AsyncTimeout(2000)]
            [HandleError(ExceptionType = typeof(TimeoutException), View = “TimedOut”)]
            public async Task<ActionResult> Index(CancellationToken cancellationToken)
            {
                ContactFormModel model = new ContactFormModel()
                    {
                        NewContact = new CreateContactModel()
                    };
                model.Contacts = await _contactRepository.GetAllAsync(cancellationToken);

                return View(model);
            }

    מעל לAction הרצוי נוסיף את ה  AsyncTimeout attribute שמציין לנו כמה זמן הפעולה יכולה להמשך מעבר לזמן המצוין שם הוא יפסיק את הפעולה.

    לפני הקריאה  לפונקציה חיצונית נכתוב await  שמורה לו איפה הוא עוצר ,משחרר את הthread וממתין לתשובה.

     

    יש לשים לב אדום:

    • שאנו באמת צריכים באתר שימוש בAsyncControllers  והבעיה שלנו היא שנוצר תור עקב פניות מרובות, אחרת קוד סינכרוני עדיף.
    • שאפילו  אם אתה משתמש בAsyncControllers  היכולות עלולות להיות מוגבלות ע”י היכולות של השרותים החיצוניים שלך.
    • אם היישום פועל מתחת ל Net 3.5. צריך לשנות את הגדרת MaxConcurrentRequestsPerCPU כברירת מחדל הוא מוגדר 12 בקשות (וזה כולל async).
      החל מ Net4. הוא מוגדר ל5000
    • אם הפעולות החיצוניות הם שאילתות SQL אז יתכן ונצטרך לשנות את כמות מספ’ ההתחברויות לADO הערך הדיפולטיבי הוא 100 פניות במקביל.

     

    לסיכום-

    בכתיבת ישום קטן , אין עניין  לערב AsyncControllers .אך אם אתה כותב יישום גדול ומנסה להגדיל את הקיבולת של השרת אז זה הפיתרון.

    רק הקפד להפעיל בדיקה מעשית ולראות שזה עונה על הצרכים שלך.