ویژگی های NET 4.5.

چاپ

تقریباً یک سالی هست که NET 4.5. ارائه شده است. اما عمده ترین مشکل نسخه اخیر مایکروسافت ارتباط برقرار کردن با توسعه دهندگان و برنامه نویسان می باشد. تنها دو یا سه ویژگی برای توسعه دهندگان شناخته شده است و مابقی ویژگی ها تنها در MSDN باقی مانده است و تبدیل یه یک سری مستندات ساده شده اند.

برای مثال هنگامی که از برنامه نویس ها بپرسید که در هسته NET 4.5. چه چیز جدیدی قرار گرفته است، اکثرشان پاسخ می دهند async و await.

شناخت و آگاهی از تمام ویژگی ها کار دشورای است. زیرا ویژگی ها با توجه به موقعیت و کاری که الان روی آن تمرکز دارید ممکن است جالب به نظر نرسد.

بنابراین در این مقاله 5 مورد از ویژگی هایی که در NET 4.5. معرفی شده است انتخاب گردیده و توضیح داده می شود.

 

این مقاله در مورد ویژگی های جدید ASP.NET و WCF و WPF و WWF بحث نمی کند. تنها به ویژگی هایی که به هسته اضافه شده است اشاره می کند.

ویژگی اول: async و await

Async و Await علائمی هستند که مکان هایی را در کد علامت گذاری می کنند که از آنجا قرار است کنترل بعد از اینکه یک Task یا Thread کامل شد ادامه پیدا کند.

اجازه دهید با زدن یک مثال و آوردن کدهای آن در ادامه مفهوم را بهتر درک کنیم.

1.()Method که در ()static void main فراخوانی می شود.

2.()Method که یک task یا thread را با نام LongTask فراخوانی می کند که این task به مدت 10 ثانیه منتظر می ماند.

3.در همان لحظه کنترل به Method بر می گردد تا ادامه کد از جایی که task صدا زده شده بود فراخونی گردد. به عبارت دیگر از آنجایی که فراخوانی چند نخی است هم LongTask اجرا می شود(10 ثانیه منتظر می ماند) و هم ادامه کدی که در Method بود اجرا می گردد.

در سناریو دیگر می خواهیم که گام سوم به صورت متفاوتی رفتار کند. ما در نظر داریم که بعد از اینکه اجرای LongTask خاتمه یافت کنترل به Method برگردد و کدهای باقیمانده اجرا شوند. برای رسیدن به این هدف async و await کلیدواژه هایی هستند که شما را کمک می کنند.

در مورد Async و await باید همواره سه نکته را مد نظر قرار دهید:

1-Async و await کلیدواژه های جفت هستند. و از آنها نمی توانید به صورت تکی استفاده کنید.

2-Async روی یک متد علامت گذاری می کند. این کلید واژه تنها یک نشانگری است برای بیان این نکته که متد مورد نظر دارای کلید واژه Await است.

3-کلید واژه await مکانی را که از آنجا task باید ادامه پیدا کند را علامتگذاری میکند.. بنابراین شما همواره این کلید واژه را همراه با کلید واژه task مشاهده می فرمایید.

در زیر نسخه تغییریافته کد قبلی را با یکدیگر مرور می کنیم.

با استفاده از Async و Await همه گام ها مشابه هستند به جز اینکه گام سوم تنها زمانی شروع به اجرا می کند که گام دوم خاتمه یابد. به عبارت دیگر کنترل زمانی به method() برمیگردد که task خاتمه یافته باشد.

حال که در مورد Async و await آموختید، اجازه دهید تا یک سوال مطرح کنیم. رفتار فوق با استفاده از Task.Wait یا Task.ContinueWith نیز قابل پیاده سازی است. تفاوت این دو را بیان نمایید. جواب به عنوان تمرین برای شما گذاشته شده است.

ویژگی دوم قابلیت زیپ ( فشرده سازی zip)

zip یکی از قابل قبول ترین فرمت های آرشیو فایل می باشد. فرمت zip تقریبا در تمام سیستم عامل ها پشتیبانی می شود.

•در سیستم عامل ویندوز این فرمت تحت عنوان "Compressed folders" پیاده سازی شده است.

•در MAC OS فرمت zip با عنوان "Archive utility" به کار رفته است.

در .NET پشتیبانی برای پیاده سازی فشرده سازی zip وجود ندارد. بسیاری از توسعه دهندگان و برنامه نویسان از کامپوننت های دیگری مانند "DotnetZip " و غیره استفاده می کنند. در .NET 4.5 ویژگی Zip داخل فریم ورک و در فضای نام System.IO.Compression قرارگرفته است.

در اولین گام لازم است که به دو فضای نام زیر ارجاع دهید:

System.IO.Compression.FileSystem
System.IO.Compression

در گام بعدی باید این دو فضای نام را وارد برنامه کنید:

using System.IO.Compression;

اگر قصد دارید تا فایل های یک فولدر را زیپ کنید، می توانید از تابع CreateFromDirectory به نحوی که در زیر نمایش داده شده است استفاده نمایید.

ZipFile.CreateFromDirectory(@"D:\data",@"D:\data.zip");

اگر می خواهید فایلها را از زیپ درآورید کافی است تا تابع ExtractToDirectory را به نحوی که در زیر نمایش داده شده است به کار بگیرید.

ZipFile.ExtractToDirectory(@"D:\data.zip", @"D:\data\unzip");

ویژگی 3: Regex timeout ) TimeOut)

"Regex" رایج ترین روش برای انجام صحت سنجی است. اما به این خاطر که regex از منطق پارس کردن مرسوم استفاده می کند در برای حملات DOS آسیب پذیر است. اجازه دهید تا با جزییات بیشتری در این مورد صحبت و منظور را واضح تر بیان کنم.

برای مثال این عبارت منظم را در نظر بگیرید: “^(\d+)$" این عبارت Regex نشان می دهد که ورودی تنها می تواند اعداد باشد. از نمودار علامت regex برای اینکه ببینید regex چگونه ارزیابی می شود می توانید استفاده کنید.

حال اجازه دهید بگوییم که برای صحت سنجی "123456X"، شش مسیر مشابه شکل زیر وجود دارد.

اما اگر یک عدد به آن اضافه کنیم، هفت مسیر پیدا می کند. بنابراین با افزایش طور عبارت regex زمان بیشتری برای ارزیابی پیدا می کند.. به عبارت دیگر مدت زمانی که ارزیابی عبارت طول می کشد رابطه خطی با طول کاراکترها دارد.

حال اجازه دهید regex مثال قبلی را قدری پیچیده تر کنیم و آن را از “^(\d+)$” به “^(\d+)+$” تغییر دهیم. اگر نگاهی به نمودار علامت regex بیندازید خواهید دید که این نمودار و این عبارت تا حدی پیچیده است. حال اگر تلاش کنیم که "123456x" را صحت سنجی کنیم، 36 مسیر برای این مهم وجود دارد که اگر تنها یک کاراکتر به آن اضافه کنیم مسیرها از 32 به 64 افزایش پیدا میکند.

به عبارت دیگر برای Regex مثال فوق مدت زمانی که طول می کشد تا صحت سنجی انجام شود تابعی نمایی از تعداد کاراکترهاست.

حال سوالی که ممکن است شما بپرسید این است: چه تفاوتی دارد؟ در پاسخ باید گفت این افزایش زمان صحت سنجی می تواند توسط هکرها استفاده شود و حملات dos توسط آنها اعمال شود. آنها می توانند یک رشته بسیار بزرگ را در ورودی بگذارند و برنامه شما را برای مدت بسیار زیادی هنگ کنند.

راه حل مناسب برای این مشکل استفاده از یک timeout برای عملیات regex است. خبر خوب اینکه در .NET 4.5 شما می توانید یک ویژگی timeout همانگونه که در کد زیر نمایش داده شده است تعریف نمایید. بنابراین اگر شما هر نوع رشته مخرب را دریافت نمودید، برنامه در یک حلقه بی نهایت نمی افتد.

try
{
var regEx = new Regex(@”^(\d+)+$”, RegexOptions.Singleline, TimeSpan.FromSeconds(2));
var match = regEx.Match(“123453109839109283090492309480329489812093809x”);
}
catch (RegexMatchTimeoutException ex)
{
Console.WriteLine(“Regex Timeout”);
}

ویژگی 4: بهینه سازی پروفایل (Improved startup performance)

همه می دانیم که کد .NET در یک فرمت نیمه کامپایل شده می باشد. در طول اجرا، کامپایلر JIT (Just-in-Time) این کد نیمه کامپایل شده IL را به کد ماشین اصلی کامپایل می کند. یکی از اشکالات و انتقادات بزرگی که به JIT وارد است عبارت است از اینکه هنکامی که برنامه .NET برای اولین بار اجرا می شود، برنامه کند است زیرا JIT مشغول ترجمه کدهای IL به کدهای ماشین است.

در .NET 4.5 برای اینکه این مدت زمان اجرا کاهش پیدا کند چیزی به نام "Profile Optimization" وجود دارد. این پروفایل چیزی به جز یک فایل ساده نیست که لیستی از متدهایی که برنامه در startup نیاز پیدا خواهد کرد را در خود دارد. بنابراین هنگامی که برنامه آغاز به کار کرد، JIT پشت صحنه اجرا می شود و شروع به ترجمه کد IL از ماشینی که برنامه روی آن اجراست به کد ماشین قابل فهم می کند.

فرایند کامپایل پشت صحنه متدها در هنگام اجرای برنامه بین چندین پردازنده تقسیم می شود تا زمان شروع برنامه بیشتر کاهش یابد. بنابراین توجه فرمایید که شما به یک جعبه چندهسته ای برای پیاده سازی بهینه سازی پروفایل نیاز دارید.

برای ایجاد پروفایل می بایست ابتدا فضای نام System.Runtime را به به برنامه اضافه نمایید. شما می توانید از متدهای SetProfileRoot و StartProfile که داخل کلاس استاتیک ProfileOptimization هستند استفاده کنید. در این حالت هنگامی که برنامه آغاز می شود، JIT پشت صحنه را اجرا می کند، که از فایل پروفایل می خواند و متدهای شروع اجرا را در پشت صحنه اجرا می کند. که این منجر به کاهش زمان شروع برنامه می گردد.

using System.Runtime; // Call the Setprofilerroot and Startprofile method
ProfileOptimization.SetProfileRoot(@"D:\ProfileFile");
ProfileOptimization.StartProfile("ProfileFile");

نکته مهم: ProfileOptimization به صورت پیش فرض در برنامه های ASP.NET 4.5 و Silverlight 5 وجود دارد. بنابراین کد بالا نیاز نیست تا برای این تکنولوژی ها مجدد نوشته شود.

ویژگی 5: زباله روب (GC background cleanup)

زباله روب در حقیقت یکی از سنگین ترین Taskها در کاربردهای .NET است. و هنگامی که در کاربردهای ASP.NET به کار می رود سنگین تر نیز می شود. کاربردهای ASP.NET روی سرور اجرا می شوند و تعدار زیادی از کلاینت ها درخواست هایی را به سرور می فرستند که منجر به بارگذاری اشیا می شود، که این قضیه زباله روب را سخت به تلاطم می اندازد که اشیایی که نیاز نیست را پاک کند.

 

در .NET 4.5 هنگامی که زباله روب شروع به تمیز کردن می کند، همه نخ های برنامه به حالت تعلیق در می آیند. در شکل بالا می توانید این روند را ببینید. در این شکل سه نخ برنامه در حال اجرا هستند. در این شکل دو زباله روب روی نخ های مجزا در حال اجرا هستند. یک نخ زباله روب برای یک پردازنده منطقی. بنابراین در حین اینکه نخ های برنامه در حال اجرای task شان هستند، آنها همچنین اشیا مدیریت شده ایجاد می کنند.

در برخی از بازه های زمانی زباله روب پشت صحنه اجرا می شود و شروع به تمیز کردن می کند. هنگامی که این زباله روب های پشت صحنه شروع به تمیز کردن می کند، آنها پاسخگویی سرور را در آن لحظه کاهش می دهند.

برای غلبه بر این مشکل زباله روب سرور معرفی شده است. در زباله روب سرور یک نخ دیگری وجود دارد که در پشت صحنه اجرا میشود. این نخ در پشت صحنه کار می کند و نسل 2 تمیز کردن اشیا را انجام می دهد بنابراین این مهم موجب کاهش سربار نخ زباله روب اصلی می گردد. به خاطر اجرای همزمان دو نخ زباله روب، نخ اصلی برنامه کمتر به حالت تعلیق در می آید. که این منجر به افزایش کارایی برنامه می شود. برای استفاده از زباله روب سرور نیاز است که از تگ xml ی با عنوان gcServer استفاده کنیم و ویژگی enable آن را True قرار دهیم

<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>

سه ویژگی بیشتر که ارزش کاوش کردن را دارد:

تنظیم Culture پیش فرض در دامنه

در نسخه های قبلی .NET هنگامی که نیاز داشتیم تا Culture را تنظیم کنیم،مجبور بودیم برای هر نخ این کار را انجام دهیم. در زیر تکه کدی را مشاهده می فرمایید که دردناک بودن تنظیم Culture را در سطح نخ نشان می دهد. این مهم واقعا در مواقعی که برنامه های چند نخی سنگینی داشتیم درد و رنج و عذاب بود.

CultureInfo cul = new CultureInfo(strCulture);
Thread.CurrentThread.CurrentCulture = cul;
Thread.CurrentThread.CurrentUICulture = cul;

در .NET 4.5 می توان تنظیمات culture را در سطح دامنه برنامه انجام داد و همه نخ هایی که داخل app domain هستند از آن Culture به ارث می برند.

در زیر تکه کدی وجود دارد که چگونگی پیاده سازی DefaultThreadCurrentCulture را نشان می دهد.


CultureInfo culture = CultureInfo.CreateSpecificCulture("fr-FR");
CultureInfo.DefaultThreadCurrentCulture = culture;

پشتیانی آرایه با طولی بیشتر از 2 گیگا بایت

البته بنده نمی دانم که در چه سناریویی ما به مجموعه ای با 2 گیگا بایت فضا نیاز داریم. بنده شخصا جایی که از این ویژگی استفاده شود را ندیده ام. اگر هم به همچین مجموعه ای نیاز پیدا کردم آن را به چند قسمت تقسیم می کنم. اما مطمئنم حتما دلیل منطقی برای فعال کردن چنین امکانی در فریم ورک وجود دارد.

پشتیبانی از Unicode در کنسول

اجازه بدهید در مورد این ویژگی تنها نام آن برده شود. به این دلیل که افراد خیلی کمی هستند که از برنامه های کنسولی استفاده کنند. در واقع افراد برای کارهای دانشگاهی و مطالعات دانشگاهی هست که از کنسول استفاده می کنند. در هر صورت در نسخه جدید .net پشتیبانی از Unicode در برنامه های کنسول وجود دارد.