نظرات مطالب
آشنایی با Refactoring - قسمت 6
البته منظور من از یک شی یا کلاس، یک کلاس است که به صورت دستی ساخته شده و نه کلاس‌های EF یا از این قبیل. امکان Expose کردن آنها به راحتی با استفاده از خصیصه‌‌ی LinqToEntitiesDomainServiceDescriptionProvider امکان پذیر است. اما در مورد یک Entity دست ساز چیزی نیافتم!
اشتراک‌ها
R4MVC معادل T4MVC برای ASP.NET Core

R4MVC is a Roslyn code generator for ASP.NET MVC Core apps that creates strongly typed helpers that eliminate the use of literal strings in many places.

It is a re-implementation of T4MVC for ASP.NET Core projects. 

R4MVC معادل T4MVC برای ASP.NET Core
مسیرراه‌ها
ASP.NET Core
ASP.NET Core 1.0
ASP.NET Core 2.0
روش ارتقاء
ASP.NET Core Identity 

کار با Areas در ASP.NET Core
کار با کوکی‌ها در ASP.NET Core
بررسی روش آپلود فایل‌ها در ASP.NET Core
ارسال ایمیل در ASP.NET Core
نوشتن Middleware سفارشی در ASP.NET Core
نوشتن TagHelperهای سفارشی برای ASP.NET Core
بررسی تغییرات Reflection در NET Core.
استفاده‌ی گسترده از DateTimeOffset در NET Core.
بررسی روش دسترسی به HttpContext در ASP.NET Core
توزیع پروژه‌های ASP.NET Core 1.1 بدون ارائه فایل‌های View آن
تغییرات رمزنگاری اطلاعات در NET Core.
ساخت بسته‌های نیوگت مخصوص NET Core.
تهیه قالب برای ارسال ایمیل‌ها در ASP.NET Core توسط Razor Viewها
روش یافتن لیست تمام کنترلرها و اکشن متدهای یک برنامه‌ی ASP.NET Core
بررسی روش آپلود فایل‌ها از طریق یک برنامه‌ی Angular به یک برنامه‌ی ASP.NET Core
سفارشی سازی صفحه‌ی اول برنامه‌های Angular CLI توسط ASP.NET Core
تغییرات Encoding در NET Core.
تغییرات متدهای بازگشت فایل‌ها به سمت کلاینت در ASP.NET Core
پیاده سازی برنامه‌های چند مستاجری در ASP.NET Core
مقدمه‌ای بر تزریق وابستگی‌ها درASP.NET Core 
نمایش خطاهای اعتبارسنجی سمت سرور ASP.NET Core در برنامه‌های Angular
احراز هویت و اعتبارسنجی کاربران در برنامه‌های Angular - قسمت اول - معرفی و ایجاد ساختار برنامه
روش استفاده‌ی صحیح از HttpClient در برنامه‌های دات نت
اجرای سرویسهای NodeJS در ASP.NET Core
بررسی خطاهای ممکن در حین راه اندازی اولیه برنامه‌های ASP.NET Core در IIS 
تست کردن متدهای یک Controller به کمک PowerShell
کار با Visual Studio در ASP.NET Core

اشتراک‌ها
NET Core SDK 3.1.403. منتشر شد

This .NET Core SDK release includes the following released .NET Core and ASP.NET Core Runtimes.

  • .NET Core SDK 3.1.403
  • .NET Core Runtime 3.1.9
  • ASP.NET Core 3.1.9 
NET Core SDK 3.1.403. منتشر شد
مطالب دوره‌ها
متدهای async تقلبی
تا اینجا مشاهده کردیم که اگر یک چنین متد زمانبری را داشته باشیم که در آن عملیاتی طولانی انجام می‌شود،
class MyService
{
  public int CalculateXYZ()
  {
    // Tons of work to do in here!
    for (int i = 0; i != 10000000; ++i)
      ;
    return 42;
  }
}
برای نوشتن معادل async آن فقط کافی است که امضای متد را به async Task تغییر دهیم و سپس داخل آن از Task.Run استفاده کنیم:
class MyService
{
  public async Task<int> CalculateXYZAsync()
  {
    return await Task.Run(() =>
    {
      // Tons of work to do in here!
      for (int i = 0; i != 10000000; ++i)
        ;
      return 42;
    });
  }
}
و ... اگر از آن در یک کد UI استفاده کنیم، ترد آن‌را قفل نکرده و برنامه، پاسخگوی سایر درخواست‌های رسیده خواهد بود. اما ... به این روش اصطلاحا Fake Async گفته می‌شود؛ یا Async تقلبی!
کاری که در اینجا انجام شده، استفاده‌ی ناصحیح از Task.Run در حین طراحی یک متد و یک API است. عملیات انجام شده در آن واقعا غیرهمزمان نیست و در زمان انجام آن، باز هم ترد جدید اختصاص داده شده را تا پایان عملیات قفل می‌کند. اینجا است که باید بین CPU-bound operations و IO-bound operations تفاوت قائل شد. اگر Entity Framework 6 و یا کلاس WebClient و امثال آن، متدهایی Async را نیز ارائه داده‌اند، این‌ها به معنای واقعی کلمه، غیرهمزمان هستند و در آن‌ها کوچکترین CPU-bound operation ایی انجام نمی‌شود.
در حلقه‌ای که در مثال فوق در حال پردازش است و یا تمام اعمال انجام شده توسط CPU، از مرزهای سیستم عبور نمی‌کنیم. نه قرار است فایلی را ذخیره کنیم، نه با اینترنت سر و کار داشته باشیم و یا مثلا اطلاعاتی را از وب سرویسی دریافت کنیم و نه هیچگونه IO-bound operation خاصی قرار است صورت گیرد.
زمانیکه برنامه نویسی قرار است با API شما کار کند و به امضای async Task می‌رسد، فرضش بر این است که در این متد واقعا یک کار غیرهمزمان در حال انجام است. بنابراین جهت بالابردن کارآیی برنامه، این نسخه را نسبت به نمونه‌ی غیرهمزمان انتخاب می‌کند.
حال تصور کنید که استفاده کننده از این API یک برنامه‌ی دسکتاپ نیست، بلکه یک برنامه‌ی ASP.NET است. در اینجا Task.Run فراخوانی شده صرفا سبب خواهد شد عملیات مدنظر، بر روی یک ترد دیگر، نسبت به ترد اصلی اختصاص داده شده توسط ASP.NET برای فراخوانی و پردازش CalculateXYZAsync، صورت گیرد. این عملیات بهینه نیست. تمام پردازش‌های درخواست‌های ASP.NET در تردهای خاص خود انجام می‌شوند. وجود ترد دوم ایجاد شده توسط Task.Run در اینجا چه حاصلی را بجز سوئیچ بی‌جهت بین تردها و همچنین بالا بردن میزان کار Garbage collector دارد؟ در این حالت نه تنها سبب بالا بردن مقیاس پذیری سیستم نشده‌ایم، بلکه میزان کار Garbage collector و همچنین سوئیچ بین تردهای مختلف را در Thread pool برنامه به شدت افزایش داده‌ایم. همچنین یک چنین سیستمی برای تدارک تردهای بیشتر و مدیریت آن‌ها، مصرف حافظه‌ی بیشتری نیز خواهد داشت.


یک اصل مهم در طراحی کدهای Async
استفاده از Task.Run در پیاده سازی بدنه متدهای غیرهمزمان، یک code smell محسوب می‌شود.


چکار باید کرد؟
اگر در کدهای خود اعمال Async واقعی دارید که IO-bound هستند، از معادل‌های Async طراحی شده برای کار با آن‌ها، مانند متد SaveChangesAsync در EF، متد DownloadStringTaskAsync کلاس WebClient و یا متدهای جدید Async کلاس Stream برای خواندن و نوشتن اطلاعات استفاده کنید. در یک چنین حالتی ارائه متدهای async Task بسیار مفید بوده و در جهت بالابردن مقیاس پذیری سیستم بسیار مؤثر واقع خواهند شد.
اما اگر کدهای شما صرفا قرار است بر روی CPU اجرا شوند و تنها محاسباتی هستند، اجازه دهید مصرف کننده تصمیم بگیرد که آیا لازم است از Task.Run برای فراخوانی متد ارائه شده در کدهای خود استفاده کند یا خیر. اگر برنامه‌ی دسکتاپ است، این فراخوانی مفید بوده و سبب آزاد شدن ترد UI می‌شود. اگر برنامه‌ی وب است، به هیچ عنوان نیازی به Task.Run نبوده و فراخوانی متداول آن با توجه به اینکه درخواست‌های برنامه‌های ASP.NET در تردهای مجزایی اجرا می‌شوند، کفایت می‌کند.

به صورت خلاصه
از Task.Run در پیاده سازی بدنه متدهای API خود استفاده نکنید.
از Task.Run در صورت نیاز (مثلا در برنامه‌های دسکتاپ) در حین فراخوانی و استفاده از متدهای API ارائه شده استفاده نمائید:
 private async void MyButton_Click(object sender, EventArgs e)
{
  await Task.Run(() => myService.CalculateXYZ());
}
در این مثال از همان نسخه‌ی غیرهمزمان متد محاسباتی استفاده شده‌است و اینبار مصرف کننده است که تصمیم گرفته در حین فراخوانی و استفاده نهایی، برای آزاد سازی ترد UI از await Task.Run استفاده کند (یا خیر).

بنابراین نوشتن یک چنین کدهایی در پیاده سازی یک API غیرهمزمان
await Task.Run(() =>
{
   for (int i = 0; i != 10000000; ++i)
     ;
});
صرفا خود را گول زدن است. کل این عملیات بر روی CPU انجام شده و هیچگاه از مرزهای IO سیستم عبور نمی‌کند.

برای مطالعه بیشتر
Should I expose asynchronous wrappers for synchronous methods
اشتراک‌ها
چکیده‌ای از Build 2019 مخصوص توسعه دهنده‌های ASP.NET Core
  • .NET Core is the future of .NET: If you’ve already started working with .NET Core, that’s great! If you’re starting a new project, you should consider .NET Core.
  • .NET Framework will continue to be supported: If you have any existing applications on .NET Framework (Windows-only), you can keep those on .NET Framework.
  • .NET Releases will become more predictable: Starting with .NET 5.0, there will be 1 major release every year,  after which each even-numbered release (6.0, 8.0, etc) will come with LTS (Long-Term Support). 
چکیده‌ای از Build 2019 مخصوص توسعه دهنده‌های ASP.NET Core
اشتراک‌ها
اضافه شدن پشتیبانی از نوع‌های DateOnly و TimeOnly به SqlClient
  • Added support for .NET 6.0. #1704
  • Added support for DateOnly and TimeOnly for SqlParameter value and GetFieldValue. #1813
  • Added support for TLS 1.3 on .NET Core and native SNI. #1821
  • Added ServerCertificate setting for Encrypt=Mandatory or Encrypt=Strict. #1822 Read more
  • Added Windows ARM64 support when targeting .NET Framework. #1828  
اضافه شدن پشتیبانی از نوع‌های DateOnly و TimeOnly به SqlClient
نظرات مطالب
ساخت بسته‌های نیوگت مخصوص NET Core.
ساخت بسته‌ی نیوگت مخصوص NET Core. و همچنین NET 4.x. (در قالب یک فایل و یک بسته‌ی نیوگت)

نکته‌ی آن‌را در اینجا می‌توانید مطالعه کنید و خلاصه‌ی آن به صورت ذیل است:
    "frameworks": {
        "net40": {
            "frameworkAssemblies": {
            }
        },

        "net45": {
            "frameworkAssemblies": {
            }
        },

        "net46": {
            "frameworkAssemblies": {
            }
        },

        "netstandard1.3": {
            "imports": "dnxcore50",
            "dependencies": {
                "NETStandard.Library": "1.6.1",
                "System.Globalization.Extensions": "4.3.0",
                "System.Reflection": "4.3.0",
                "System.Reflection.TypeExtensions": "4.3.0"
            }
        }
    },
قسمت dependencies واقع در ریشه‌ی فایل project.json حذف شده و به ذیل قسمت netstandard انتقال پیدا می‌کند. همچنین به ازای فریم‌ورک‌های مختلف 4x مدنظر، یک مدخل مرتبط در قسمت frameworks اضافه می‌شود.
همین مقدار تغییر به همراه نکته‌ی scripts -> postcompile ابتدای بحث جاری، سبب خواهد شد تا کتابخانه‌ی جاری برای تمام فریم ورک‌های یاد شده به صورت مجزا کامپایل شده و درون بسته‌ی نیوگت نهایی قرار گیرد:


در این حالت ممکن است قسمتی از کدها مثلا برای دات نت 4 قابل استفاده نباشند و نیاز به تغییر داشته باشند. برای این حالت باید از if directives# جهت شرطی کردن کامپایلر کمک گرفت:
#if NET40
// This only compiles for the .NET Framework 4 targets
#else
// This compiles for all other targets
#endif