فکر میکنم از این رهیافت در سلوشنهای مرجح مایکروسافت نشه یاد کرد. در asp.net mvc 4 دو تکنیک Bundle کردن (دسته کردن فایلهای مشابه در یک دسته) و Minify کردن (از بین بردن فواصل اضافه و کوچک کردن نام متغییرها و حذف کامنتها) اضافه شده. که این کار رو به صورت توکار خود فریمورک انجام میده فقط لازمه با دستورات Syte.Render و Script.Render اونارو آدرس دهی کنیم.
همچنین این قابلیت وجود دارد که در زمان debug فایلها رو خانا و قابلفهم مشاهده کنید. در یکی از سری پستهای آقای شهروز جعفری ^ این مهم اشاره کردن. هرچند پست ایشان اندکی قدیمی است(موقع نگارش beta مطلب منتشر شد که حالا با آمدن نگارش RC اندکی فرق کرده است)
اگر برنامههای مبتنی بر SQL Server خود را به EF 7.0 ارتقاء دهید، در حین اجرای برنامه، به خطای زیر برخواهید خورد:
علت اینجا است که پروایدر SQL Server مخصوص EF 7.0، از نگارش جدید Microsoft.Data.SqlClient استفاده میکند و در این نگارش، تنظیم Encrypt=True، به صورت پیشفرض اعمال شدهاست. این تنظیم، پیشتر به صورت Encrypt=False وجود داشت و به همین جهت عموما در حین تعریف رشتههای اتصالی دیده نمیشد.
اگر نیاز به استفادهی از پرچم Encrypt=True وجود داشته باشد:
- باید سرور اس کیوال با یک certificate معتبر تنظیم شود.
- کلاینت باید این certificate را تائید کند. اگر کلاینت چنین قصدی را ندارد، میتواند تنظیم TrustServerCertificate=True را به رشتهی اتصالی اضافه کند.
در غیراینصورت، خطای ذکر شده را دریافت خواهیم کرد.
برای رفع این مشکل یا باید رمزنگاری اتصالات را در SQL Server پیاده سازی کرد و یا از این پس، ذکر پرچم Encrypt=False در انتهای رشتهی اتصالی به آن، ضروری است. برای مثال یک نمونه رشتهی اتصالی تغییر یافتهی بر اساس این تنظیم، به صورت زیر است:
بدیهی است این تغییر مختص به EF 7.0 نیست و تمام برنامههایی که از ADO.NET و نگارش جدید Microsoft.Data.SqlClient استفاده میکنند، باید به آن توجه داشته باشند.
A connection was successfully established with the server, but then an error occurred during the login process. (provider: SSL Provider, error: 0 - The certificate chain was issued by an authority that is not trusted.)
اگر نیاز به استفادهی از پرچم Encrypt=True وجود داشته باشد:
- باید سرور اس کیوال با یک certificate معتبر تنظیم شود.
- کلاینت باید این certificate را تائید کند. اگر کلاینت چنین قصدی را ندارد، میتواند تنظیم TrustServerCertificate=True را به رشتهی اتصالی اضافه کند.
در غیراینصورت، خطای ذکر شده را دریافت خواهیم کرد.
برای رفع این مشکل یا باید رمزنگاری اتصالات را در SQL Server پیاده سازی کرد و یا از این پس، ذکر پرچم Encrypt=False در انتهای رشتهی اتصالی به آن، ضروری است. برای مثال یک نمونه رشتهی اتصالی تغییر یافتهی بر اساس این تنظیم، به صورت زیر است:
Data Source=.\\SQLEXPRESS;Initial Catalog=MyTestDb;Integrated Security=true;Encrypt=False;
بدیهی است این تغییر مختص به EF 7.0 نیست و تمام برنامههایی که از ADO.NET و نگارش جدید Microsoft.Data.SqlClient استفاده میکنند، باید به آن توجه داشته باشند.
این مشکلات زمان VB6 (مرحوم) هم بود (مثلا هنگام انتخاب فونت برای یک متن فارسی باید script آن را در صفحه انتخاب فونت روی Arabic گذاشت تا درست نمایش داده شود). قبل از دات نت. قبل از یونیکد شدن رشتهها در سیستمهای متداول دات نت به صورت پیش فرض از نگارش یک آن.
دلفیهای جدید هم به نظر رشته یونیکد را پیش فرض خود کردهاند (نگارشهای بعد از 2007). بهتر است برنامه خودتون رو به این نگارشها ارتقاء بدید (تا به صورت خودکار همه چیز منجمله کامپوننتها(ی جدید) بر مبنای رشتههای یونیکد کار کنند)، همچنین بانک اطلاعاتی هم باید واقعا رشتههای یونیکد را ساپورت کند. مثلا در SQL Server ، بین نوعهای varchar و nvarchar تفاوت وجود دارد.
در کل من با این صفحه کلید و برنامههای دات نت، نه مشکلی در ثبت دارم و نه مشکلی در نمایش (چند سال هست). همچنین نیم فاصله هم جهت تایپ فارسی پشتیبانی میشود + ساپورت فونتهای قدیمی هم لحاظ شده.
دلفیهای جدید هم به نظر رشته یونیکد را پیش فرض خود کردهاند (نگارشهای بعد از 2007). بهتر است برنامه خودتون رو به این نگارشها ارتقاء بدید (تا به صورت خودکار همه چیز منجمله کامپوننتها(ی جدید) بر مبنای رشتههای یونیکد کار کنند)، همچنین بانک اطلاعاتی هم باید واقعا رشتههای یونیکد را ساپورت کند. مثلا در SQL Server ، بین نوعهای varchar و nvarchar تفاوت وجود دارد.
در کل من با این صفحه کلید و برنامههای دات نت، نه مشکلی در ثبت دارم و نه مشکلی در نمایش (چند سال هست). همچنین نیم فاصله هم جهت تایپ فارسی پشتیبانی میشود + ساپورت فونتهای قدیمی هم لحاظ شده.
خلاصهای را در مورد SQL Server CE قبلا در این سایت مطالعه کردهاید. در ادامه خلاصهای کاربردی را از تنظیمات و نکات مرتبط به کار با SQL-CE به کمک NHibernate ملاحظه خواهید نمود:
1) دریافت SQL-CE 4.0
همین مقدار برای استفاده از SQL-CE 4.0 به کمک NHibernate کفایت میکند و حتی نیازی به نصب سرویس پک یک VS 2010 هم نیست.
2) ابزار سازی جهت ایجاد یک بانک اطلاعاتی خالی SQL-CE
using System;
using System.IO;
namespace NHibernate.Helper.DbSpecific
{
public class SqlCEDbHelper
{
const string engineTypeName = "System.Data.SqlServerCe.SqlCeEngine, System.Data.SqlServerCe";
/// <summary>
/// note: this method will delete existing db and then creates a new one.
/// </summary>
/// <param name="filename"></param>
/// <param name="password"></param>
public static void CreateEmptyDatabaseFile(string filename, string password = "")
{
if (File.Exists(filename))
File.Delete(filename);
var type = System.Type.GetType(engineTypeName);
var localConnectionString = type.GetProperty("LocalConnectionString");
var createDatabase = type.GetMethod("CreateDatabase");
var engine = Activator.CreateInstance(type);
string connectionStr = string.Format("Data Source='{0}';Password={1};Encrypt Database=True", filename, password);
if (string.IsNullOrWhiteSpace(password))
connectionStr = string.Format("Data Source='{0}'", filename);
localConnectionString.SetValue(
obj: engine,
value: connectionStr,
index: null);
createDatabase.Invoke(engine, new object[0]);
}
/// <summary>
/// use this method to compact or encrypt existing db or decrypt it to a new db with all records
/// </summary>
/// <param name="sourceConnection"></param>
/// <param name="destConnection"></param>
public static void CompactDatabase(string sourceConnection, string destConnection)
{
var type = System.Type.GetType(engineTypeName);
var engine = Activator.CreateInstance(type);
var localConnectionString = type.GetProperty("LocalConnectionString");
localConnectionString.SetValue(
obj: engine,
value: sourceConnection,
index: null);
var compactDatabase = type.GetMethod("Compact");
compactDatabase.Invoke(engine, new object[] { destConnection });
}
}
}
کلاس فوق، یک کلاس عمومی است و مرتبط به NHibernate نیست و در همه جا قابل استفاده است.
متد CreateEmptyDatabaseFile یک فایل بانک اطلاعاتی خالی با فرمت مخصوص SQL-CE را برای شما تولید خواهد کرد. به این ترتیب میتوان بدون نیاز به ابزار خاصی، سریعا یک بانک خالی را تولید و شروع به کار کرد. در این متد اگر کلمه عبوری را وارد نکنید، بانک اطلاعاتی رمزنگاری شده نخواهد بود و اگر کلمه عبور را وارد کنید، دیتابیس اولیه به همراه کلیه اعمال انجام شده بر روی آن در طول زمان، با کمک الگوریتم AES به صورت خودکار رمزنگاری خواهند شد. کل کاری را هم که باید انجام دهید ذکر این کلمه عبور در کانکشن استرینگ است.
متد CompactDatabase، یک متد چند منظوره است. اگر بانک اطلاعاتی SQL-CE رمزنگاری نشدهای دارید و میخواهید کل آنرا به همراه تمام اطلاعات درون آن رمزنگاری کنید، میتوانید جهت سهولت کار از این متد استفاده نمائید. آرگومان اول آن به کانکشن استرینگ بانکی موجود و آرگومان دوم به کانکشن استرینگ بانک جدیدی که تولید خواهد شد، اشاره میکند.
همچنین اگر یک بانک اطلاعاتی SQL-CE رمزنگاری شده دارید و میخواهید آنرا به صورت یک بانک اطلاعاتی جدید به همراه تمام رکوردهای آن رمزگشایی کنید، باز هم میتوان از این متد استفاده کرد. البته بدیهی است که کلمه عبور را باید داشته باشید و این کلمه عبور جایی درون فایل بانک اطلاعاتی ذخیره نمیشود. در این حالت در کانکشن استرینگ اول باید کلمه عبور ذکر شود و کانکشن استرینگ دوم نیازی به کلمه عبور نخواهد داشت.
فرمت کلی کانکشن استرینگ SQL-CE هم به شکل زیر است:
Data Source=c:\path\db.sdf;Password=1234;Encrypt Database=True
البته این برای حالتی است که قصد داشته باشید بانک اطلاعاتی مورد استفاده را رمزنگاری کنید یا از یک بانک اطلاعاتی رمزنگاری شده استفاده نمائید. اگر بانک اطلاعاتی شما کلمه عبوری ندارد، ذکر Data Source=c:\path\db.sdf کفایت میکند.
این کلاس هم از این جهت مطرح شد که NHibernate میتواند ساختار بانک اطلاعاتی را بر اساس تعاریف نگاشتها به صورت خودکار تولید و اعمال کند، «اما» بر روی یک بانک اطلاعاتی خالی SQL-CE از قبل تهیه شده (در غیراینصورت خطای The database file cannot be found. Check the path to the database را دریافت خواهید کرد).
نکته:
اگر دقت کرده باشید در این کلاس engineTypeName به صورت رشته ذکر شده است. چرا؟
علت این است که با ذکر engineTypeName به صورت رشته، میتوان از این کلاس در یک کتابخانه عمومی هم استفاده کرد، بدون اینکه مصرف کننده نیازی داشته باشد تا ارجاع مستقیمی را به اسمبلی SQL-CE به برنامه خود اضافه کند. اگر این ارجاع وجود داشت، متدهای یاد شده کار میکنند، در غیراینصورت در گوشهای ساکت و بدون دردسر و بدون نیاز به اسمبلی خاصی برای روز مبادا قرار خواهند گرفت.
3) ابزار مرور اطلاعات بانک اطلاعاتی SQL-CE
با استفاده از management studio خود SQL Server هم میشود با بانکهای اطلاعاتی SQL-CE کار کرد، اما ... اینبار برخلاف نگارش کامل اس کیوال سرور، با یک نسخهی بسیار بدوی، که حتی امکان rename فیلدها را هم ندارد مواجه خواهید شد. به همین جهت به شخصه برنامه SqlCe40Toolbox را ترجیح میدهم و اطمینان داشته باشید که امکانات آن برای کار با SQL-CE از امکانات ارائه شده توسط management studio مایکروسافت، بیشتر و پیشرفتهتر است!
4) تنظیمات NHibernate جهت کار با SQL-CE
الف) پس از نصب SQL-CE ، فایلهای آنرا در مسیر C:\Program Files\Microsoft SQL Server Compact Edition\v4.0 میتوان یافت. درایور ADO.NET آن هم در مسیر C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Desktop قرار دارد. بنابراین در ابتدا نیاز است تا ارجاعی را به اسمبلی System.Data.SqlServerCe.dll به برنامه خود اضافه کنید (نام پوشه desktop آن هم غلط انداز است. از این جهت که نگارش 4 آن، به راحتی در برنامههای ذاتا چند ریسمانی ASP.Net بدون مشکل قابل استفاده است).
نکته مهم: در این حالت NHibernate قادر به یافتن فایل درایور یاد شده نخواهد بود و پیغام خطای «Could not create the driver from NHibernate.Driver.SqlServerCeDriver» را دریافت خواهید کرد. برای رفع آن، اسمبلی System.Data.SqlServerCe.dll را در لیست ارجاعات برنامه یافته و در برگه خواص آن، خاصیت «Copy Local» را true کنید. به این معنا که NHibernate این اسمبلی را در کنار فایل اجرایی برنامه شما جستجو خواهد کرد.
ب) مطلب بعد، تنظیمات ابتدایی NHibernate است جهت شناساندن SQL-CE . مابقی مسایل (نکات mapping، کوئریها و غیره) هیچ تفاوتی با سایر بانکهای اطلاعاتی نخواهد داشت و یکی است. به این معنا که اگر برنامه شما از ویژگیهای خاص بانکهای اطلاعاتی استفاده نکند (مثلا اگر از رویههای ذخیره شده اس کیوال سرور استفاده نکرده باشد)، فقط با تغییر کانکشن استرینگ و معرفی dialect و driver جدید، به سادگی میتواند به یک بانک اطلاعاتی دیگر سوئیچ کند؛ بدون اینکه حتی بخواهید یک سطر از کدهای اصلی برنامه خود را تغییر دهید.
تنها نکته جدید آن این متد است:
private Configuration getConfig()
{
var configure = new Configuration();
configure.SessionFactoryName("BuildIt");
configure.DataBaseIntegration(db =>
{
db.ConnectionProvider<DriverConnectionProvider>();
db.Dialect<MsSqlCe40Dialect>();
db.Driver<SqlServerCeDriver>();
db.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
db.IsolationLevel = IsolationLevel.ReadCommitted;
db.ConnectionString = ConnectionString;
db.Timeout = 10;
//for testing ...
db.LogFormattedSql = true;
db.LogSqlInConsole = true;
});
return configure;
}
که در آن نحوه تعریف MsSqlCe40Dialect و SqlServerCeDriver مشخص شده است.
نکته حاشیهای!
در این مثال primary key از نوع identity تعریف شده و بدون مشکل کار کرد. همین را اگر با EF تست کنید، این خطا را دریافت میکنید: «Server-generated keys and server-generated values are not supported by SQL Server Compact». بله، EF نمیتواند با primary key از نوع identity حین کار با SQL-CE کار کند. برای رفع آن توصیه شده است که از Guid استفاده کنید!
نکته تکمیلی:
استفاده از Dialect سفارشی در NHibernate
نکته پایانی!
و در پایان باید اشاره کرد که SQL-CE یک بانک اطلاعاتی نوشته شده با دات نت نیست (با CPP نوشته شده است و نصب آن هم نیاز به ران تایم به روز VC را دارد). به این معنا که جهت سیستمهای 64 بیتی و 32 بیتی باید نسخه مناسب آنرا توزیع کنید. یا اینکه Target platform پروژه جاری دات نت خود را بر روی X86 قرار دهید (نه بر روی Any CPU پیش فرض) و در این حالت تنها یک نسخه X86 بانک اطلاعاتی SQL-CE و همچنین برنامه خود را برای تمام سیستمها توزیع کنید.
In September of 2014, at the ng-Europe conference, the Angular team announced what would be known as Angular 2.Is was a drastic change that left many developers angry. One of the main sources of complaint was the lack of a migration path.
در سال 2014 و با معرفی آنگولار 2، که یک rewrite کامل از فریم ورک آنگولار بود، بسیاری از توسعه دهندگان بخاطر تغییرات اساسی به سمت فریم ورکهای دیگر از جمله کتابخانهی ری اکت کوچ کردند.
مطالب
معرفی ES 6
جاوا اسکریپت، پیاده سازی ECMA Script است (با تلفظ اکما اسکریپت) که به صورت مخفف به آن ES هم گفته میشود و ES 6، در حقیقت نگارش 6 این استاندارد است که به آن ECMA Script 2015 نیز میگویند (زمان نهایی شدن استاندارد آن سال 2015 است) و از زمان ارائهی جاوا اسکریپت، بزرگترین تغییر و تحول آن نیز محسوب میگردد. با ES 6 مواردی مانند کلاسها، برنامه نویسی تابعی (functional programming)، ماژولها و غیره اضافه شدهاند.
چرا باید ES 6 را آموخت؟
در طی 2 سال آینده، تمام فریم ورکهای جدید جاوا اسکریپتی، از بوت استرپ 4 تا AngularJS 2 تا Aurelia و غیره، همگی به ES 6 کوچ خواهند کرد (و این اتفاق هم اکنون در حال رخ دادن است). بنابراین به زودی بدون فراگیری و تسلط بر ES 6، در حوزهی وب، «بیسواد» محسوب خواهید شد و فراگیری آن یک «باید» است.
وضعیت پشتیبانی از ES 6 در مرورگرهای مختلف
برای مشاهدهی پیشرفتهای مرورگرهای کنونی در زمینهی پشتیبانی از ES 6، میتوان به صفحهی ES 6 compatibility table مراجعه کرد.
برای نمونه در حال حاضر، فایرفاکس بهترین پشتیبانی از ES 6 را ارائه میدهد (با پیاده سازی 85 درصد از قابلیتها) و بعد از آن مرورگر جدید مایکروسافت قرار دارد.
وضعیت IE 10,11 در این بین تغییری نخواهند کرد؛ زیرا پشتیبانی رسمی از تمام آنها به زودی خاتمه مییابد (در سه شنبه، ۲۲ دی ۱۳۹۴).
در همین صفحه، در ابتدای چارت، ستون current browser نیز قرار دارد. این ستون، وضعیت مرورگر جاری شما را از لحاظ درصد پیاده سازی قابلیتهای ES 6 نمایش میدهد.
اهمیت دریافت آخرین نگارشهای مرورگرها
با توجه به ES 6 compatibility table، اکثر مرورگرها در نسخههای شبانه و همچنین آزمایشی آنها، به مرور در حال افزودن قابلیتهای باقیماندهی ES 6 هستند. بنابراین اگر با فایرفاکس کار میکنید، نیاز است Firefox nightly builds را نصب کنید. اگر از مرورگرهای مایکروسافت استفاده میکنید، آخرین نگارش MS Edge بهترین پشتیبانی از ES 6 را ارائه میدهد و اگر از کروم استفاده میکنید، نگارشهای بتا و Dev آن را میتوانید دریافت کنید.
علاوه بر اینها، نگارشهای فعلی این مرورگرها نیز دارای امکانات آزمایشی هستند که میتوان آنها را به صورت دستی فعال کرد. برای مثال در مرورگر کروم، به آدرس chrome://flags مراجعه کنید و در صفحهی باز شده، کلمهی JavaScript را جستجو کنید. در اینجا نیاز است گزینهی «Enable Experimental JavaScript» را فعال کنید (بر روی لینک enable ذیل آن کلیک نمائید).
به این ترتیب قادر خواهید بود آخرین افزونههای ES 6 را در developer tools console آن اجرا کنید.
چنین تنظیمی به MS Edge نیز اضافه شدهاست. پس از اجرای آن، به آدرس about:flags مراجعه کنید:
در اینجا نیز میتوانید گزینهی «Enable experimental JavaScript features» را انتخاب کنید.
معرفی traceur-compiler
هرچند قابلیتهای فعلی آخرین نگارشهای مرورگرها برای اجرای بسیاری از امکانات ES 6 کفایت میکنند، اما اگر علاقمند به اجرای تمامی آنها هستید، میتوان از traceur-compiler گوگل نیز کمک گرفت (با تلفظ تریسر). این کامپایلر، قابلیتهای جدید ES 6 را تبدیل به نگارشهای فعلی قابل درک برای مرورگرهای قدیمیتر میکند. به این ترتیب امکان اجرای آزمایشات مرتبط با ES 6 را خواهید یافت.
روش استفادهی از آن هم به صورت ذیل است:
ابتدا نیاز است دو اسکریپت اصلی تریسر را به صفحه الحاق کنید. پس از آن نوع تگ اسکریپت را به module تنظیم کنید. در این بین قادر خواهید بود به تمامی امکانات ES 6 در مرورگر فعلی خود دسترسی داشته باشید.
چرا باید ES 6 را آموخت؟
در طی 2 سال آینده، تمام فریم ورکهای جدید جاوا اسکریپتی، از بوت استرپ 4 تا AngularJS 2 تا Aurelia و غیره، همگی به ES 6 کوچ خواهند کرد (و این اتفاق هم اکنون در حال رخ دادن است). بنابراین به زودی بدون فراگیری و تسلط بر ES 6، در حوزهی وب، «بیسواد» محسوب خواهید شد و فراگیری آن یک «باید» است.
وضعیت پشتیبانی از ES 6 در مرورگرهای مختلف
برای مشاهدهی پیشرفتهای مرورگرهای کنونی در زمینهی پشتیبانی از ES 6، میتوان به صفحهی ES 6 compatibility table مراجعه کرد.
برای نمونه در حال حاضر، فایرفاکس بهترین پشتیبانی از ES 6 را ارائه میدهد (با پیاده سازی 85 درصد از قابلیتها) و بعد از آن مرورگر جدید مایکروسافت قرار دارد.
وضعیت IE 10,11 در این بین تغییری نخواهند کرد؛ زیرا پشتیبانی رسمی از تمام آنها به زودی خاتمه مییابد (در سه شنبه، ۲۲ دی ۱۳۹۴).
در همین صفحه، در ابتدای چارت، ستون current browser نیز قرار دارد. این ستون، وضعیت مرورگر جاری شما را از لحاظ درصد پیاده سازی قابلیتهای ES 6 نمایش میدهد.
اهمیت دریافت آخرین نگارشهای مرورگرها
با توجه به ES 6 compatibility table، اکثر مرورگرها در نسخههای شبانه و همچنین آزمایشی آنها، به مرور در حال افزودن قابلیتهای باقیماندهی ES 6 هستند. بنابراین اگر با فایرفاکس کار میکنید، نیاز است Firefox nightly builds را نصب کنید. اگر از مرورگرهای مایکروسافت استفاده میکنید، آخرین نگارش MS Edge بهترین پشتیبانی از ES 6 را ارائه میدهد و اگر از کروم استفاده میکنید، نگارشهای بتا و Dev آن را میتوانید دریافت کنید.
علاوه بر اینها، نگارشهای فعلی این مرورگرها نیز دارای امکانات آزمایشی هستند که میتوان آنها را به صورت دستی فعال کرد. برای مثال در مرورگر کروم، به آدرس chrome://flags مراجعه کنید و در صفحهی باز شده، کلمهی JavaScript را جستجو کنید. در اینجا نیاز است گزینهی «Enable Experimental JavaScript» را فعال کنید (بر روی لینک enable ذیل آن کلیک نمائید).
به این ترتیب قادر خواهید بود آخرین افزونههای ES 6 را در developer tools console آن اجرا کنید.
چنین تنظیمی به MS Edge نیز اضافه شدهاست. پس از اجرای آن، به آدرس about:flags مراجعه کنید:
در اینجا نیز میتوانید گزینهی «Enable experimental JavaScript features» را انتخاب کنید.
معرفی traceur-compiler
هرچند قابلیتهای فعلی آخرین نگارشهای مرورگرها برای اجرای بسیاری از امکانات ES 6 کفایت میکنند، اما اگر علاقمند به اجرای تمامی آنها هستید، میتوان از traceur-compiler گوگل نیز کمک گرفت (با تلفظ تریسر). این کامپایلر، قابلیتهای جدید ES 6 را تبدیل به نگارشهای فعلی قابل درک برای مرورگرهای قدیمیتر میکند. به این ترتیب امکان اجرای آزمایشات مرتبط با ES 6 را خواهید یافت.
روش استفادهی از آن هم به صورت ذیل است:
<script src="https://google.github.io/traceur-compiler/bin/traceur.js"></script> <script src="https://google.github.io/traceur-compiler/src/bootstrap.js"></script> <script type="module"> // ES 6 </script>
فرض کنید که از یک برنامهی native ویندوز برای تهیه تصاویر سایتها در یک برنامهی وب استفاده میکنید و صبح که به سایت سر زدهاید پیام در دسترس نبودن سایت قابل مشاهده است. مشکل از کجا است؟!
یک مثال ساده
برنامهی کنسول فوق را پس از فعال سازی Allow unsafe code در قسمت تنظیمات پروژه، کامپایل کرده و سپس آنرا خارج از VS.NET اجرا کنید. احتمالا انتظار دارید که قسمت catch این کد حداقل اجرا شود و سپس سطر «کلیدی را فشار دهید» ظاهر گردد. اما ... خیر! کل پروسه کرش کرده و هیچ پیام خطایی را دریافت نخواهید کرد. اگر به لاگهای ویندوز مراجعه کنید پیام زیر قابل مشاهده است:
و این نوع مسایل هنگام کار با کتابخانههای C و ++C زیاد ممکن است رخ دهند. نمونهی آن استفاده از WebControl دات نت است یا هر برنامهی native دیگری. در این حالت اگر برنامهی شما یک برنامهی وب باشد، عملا سایت از کار افتادهاست. به عبارتی پروسهی ویندوزی آن کرش کرده و بلافاصله از طرف ویندوز خاتمه یافته است.
چرا قسمت catch اجرا نشد؟
از دات نت 4 به بعد، زمانیکه دسترسی غیرمجازی به حافظه صورت گیرد، برای مثال دسترسی به یک pointer آزاد شده، استثنای حاصل، توسط برنامه catch نشده و اجازه داده میشود تا برنامه کلا کرش کند. به این نوع استثناءها Corrupted State Exceptions یا CSE گفته میشود. اگر نیاز به مدیریت آنها توسط برنامه باشد، باید به یکی از دو طریق زیر عمل کرد:
الف) از ویژگی HandleProcessCorruptedStateExceptions بر روی متد فراخوان کتابخانهی native باید استفاده شود. برای مثال در کدهای فوق خواهیم داشت:
ب) و یا فایل کانفیگ برنامه را ویرایش کرده و چند سطر ذیل را به آن اضافه کنید:
در این حالت مدیریت اینگونه خطاها در کل برنامه همانند برنامههای تا دات نت 3.5 خواهد شد.
یک مثال ساده
using System; namespace AccessViolationExceptionSample { class Program { private static unsafe void AccessViolation() { byte b = *(byte*)(8762765876); } static void Main(string[] args) { try { AccessViolation(); } catch (Exception ex) { Console.WriteLine(ex); } Console.WriteLine("Press a key..."); Console.ReadKey(); } } }
System.AccessViolationException. Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
چرا قسمت catch اجرا نشد؟
از دات نت 4 به بعد، زمانیکه دسترسی غیرمجازی به حافظه صورت گیرد، برای مثال دسترسی به یک pointer آزاد شده، استثنای حاصل، توسط برنامه catch نشده و اجازه داده میشود تا برنامه کلا کرش کند. به این نوع استثناءها Corrupted State Exceptions یا CSE گفته میشود. اگر نیاز به مدیریت آنها توسط برنامه باشد، باید به یکی از دو طریق زیر عمل کرد:
الف) از ویژگی HandleProcessCorruptedStateExceptions بر روی متد فراخوان کتابخانهی native باید استفاده شود. برای مثال در کدهای فوق خواهیم داشت:
[HandleProcessCorruptedStateExceptions] static void Main(string[] args) {
<?xml version="1.0" encoding="utf-8" ?> <configuration> <runtime> <legacyCorruptedStateExceptionsPolicy enabled="true" /> </runtime> </configuration>