عنوان:

‫پیاده سازی ساده Google Recaptcha در ASP.NET MVC


نویسنده: س علیزاده
تاریخ: ۱۳۹۷/۰۱/۱۷ ۱۶:۳۹
آدرس: www.dntips.ir
The Google reCaptcha For ASP.NET MVC Web Apps  


مشاهده مطلب اصلی

نظرات

  • وحید نصیری در ۱۳۹۷/۰۱/۱۷ ۱۹:۳۳
    چند نکته در جهت بهبود کیفیت کدهای آن

    - یک چنین سطری در برنامه‌های ASP.NET نباید وجود داشته باشد:
    if (!Task.Run(() => client.IsAcceptAsync(response, secretkey)).Result)
    کلا ASP.NET MVC 5.x روشی را برای اجرای async اکشن فیلترها ندارد. البته این محدودیت در نگارش Core برطرف شده‌است.
    اگر در نگارش 5x از Task.Run استفاده کنید، سبب بروز این مشکلات خواهید شد:
    - تداخل با thread pool خود ASP.NET که سبب کاهش کارآیی برنامه با مصرف تردی اضافی می‌شود.
    - سبب اجرای قطعه کد قرار گرفته‌ی درون آن، خارج از  request context جاری می‌شود.
    یعنی در اینجا یک ترد جدید را ایجاد کردید و همچنین با استفاده از Result اجرای غیرهمزمان کدهای داخل آن‌را سد کردید. این یک سطر باز هم غیرهمزمان اجرا می‌شود. بنابراین نیازی به Task.Run ندارد؛ چون با مصرف کردن یک ترد اضافی، جلوی پاسخ‌دهی برنامه را به یک درخواست ممکن می‌گیرد.
    همچنین بجای استفاده‌ی از Result هم به این صورت عمل کنید:
    if (!client.IsAcceptAsync(response, secretkey).GetAwaiter().GetResult())

    - از قطعه کد زیر استفاده نکنید. اطلاعات بیشتر
    using (var client = new HttpClient())
    • احمد رجبی در ۱۳۹۷/۰۱/۱۸ ۱۱:۰
      یک راه دیگر :
      public static class AsyncHelper  
      {
          private static readonly TaskFactory _taskFactory = new
              TaskFactory(CancellationToken.None,
                          TaskCreationOptions.None,
                          TaskContinuationOptions.None,
                          TaskScheduler.Default);
      
          public static TResult RunSync<TResult>(Func<Task<TResult>> func)
              => _taskFactory
                  .StartNew(func)
                  .Unwrap()
                  .GetAwaiter()
                  .GetResult();
      
          public static void RunSync(Func<Task> func)
              => _taskFactory
                  .StartNew(func)
                  .Unwrap()
                  .GetAwaiter()
                  .GetResult();
      }
      نحوه استفاده  
      AsyncHelper.RunSync(() => client. IsAcceptAsync ( response ,  secretkey ));

      • وحید نصیری در ۱۳۹۷/۰۱/۱۸ ۱۱:۲۱
        taskFactory.StartNew و Task.Run، هر دوی این‌ها یک ترد جدید را آغاز می‌کنند که در برنامه‌های ASP.NET نیازی به آن‌ها نیست. تعداد ترد مصرفی کمتر در برنامه‌های وب = امکان پاسخگویی بیشتر برنامه. همچنین هر دوی این‌ها هم کد مربوطه را خارج از context درخواست جاری اجرا می‌کنند. برای مثال اگر متد IsAcceptAsync (یا هر متد دیگری) در بدنه‌اش از اطلاعات HttpContext جاری استفاده می‌کند، این اطلاعات نال خواهند بود، چون در یک context دیگر در حال اجرا است.
        کدی را که نوشتید برای برنامه‌های دسکتاپ بیشتر استفاده می‌شود تا ترد UI را هرچند مدتی اندک مشغول نکند.
        برای مطالعه‌ی بیشتر
        - متدهای async تقلبی 
        - Task.Run Etiquette and Proper Usage 
        - StartNew is Dangerous  
        • احمد رجبی در ۱۳۹۷/۰۱/۱۸ ۱۲:۴۰
          با تشکر.
          بله بستگی به نحوه استفاده و ملزومات برنامه خواهد بود.
    • وحید نصیری در ۱۳۹۷/۰۱/۲۰ ۱۷:۲۱
      یک نکته‌ی تکمیلی در مورد فراخوانی sync متدهای async

      متد async کتابخانه‌ای که Result بر روی آن فراخوانی می‌شود، نیاز به ConfigureAwait(false) دارد (در تمام فریم ورک‌های دات نتی، غیر از NET Core.)؛ در غیراینصورت منتظر وقوع یک deadlock باشید. اطلاعات بیشتر