اگر علاقمند باشید که شیرپوینت مایکروسافت را نصب و راه اندازی کنید، مجموعه زیر به صورت قدم به قدم به همراه توضیحات و تصاویر کافی نحوه انجام اینکار را بر روی یک virtual pc توضیح داده است:
البته اگر برنامه نویس ASP.Net باشید بسیاری از موارد آن برای شما تکراری خواهد بود.
- قسمت 1 : نصب IIS و دات نت فریم ورک 2
- قسمت 2 : تنظیمات ایمیل پاپ 3
- قسمت 3: نصب و راه اندازی آوت لوک 2007
- قسمت 4: تنظیمات دات نت فریم ورک
- قسمت 5: نصب اس کیوال سرور 2005
- قسمت 6: تنظیمات اس کیوال سرور 2005
- قسمت 7: نصب سرویس پک اس کیوال سرور 2005
- قسمت 8: ایجاد اکانتهای لازم برای نصب MOSS
- قسمت 9: نصب شیر پوینت 2007
- قسمت 10: تنظیمات امنیتی اینترنت اکسپلورر
- قسمت 11: تنظیمات سرویسهای مربوطه
- قسمت 12: ایجاد یک Shared Services Provider
- قسمت 13: تنظیمات قسمت جستجو
- قسمت 14: تنظیمات ایمیل خروجی شیرپوینت
- قسمت 15: ایجاد یک پرتال
- قسمت 16: نصب SharePoint Designer 2007
- قسمت 17: نصب برنامههای آفیس 2007
- قسمت 18: نصب اسکریپتهای Warm-up بر روی VPC
- قسمت 19: بهینه سازی VPC برای اجرای شیرپوینت 2007
- قسمت 20: استفاده از گزینه Differencing یک VPC برای تهیه چندین ماشین مجازی بر اساس یک منبع موجود
انتشار PostSharp 5.0 RTM
PostSharp 5.0 adds support for .NET Core 1.1, Visual Studio 2017 and C# 7.0. It also introduces brand new features like the [Cache] aspect, the [Command] and [DependencyProperty] aspects for XAML applications. And the Logging feature has been completely revamped, now fully customizable and faster than ever.
Any experienced .NET developer knows that even though .NET applications have a garbage collector, memory leaks occur all the time. It’s not that the garbage collector has bugs, it’s just that there are ways we can (easily) cause memory leaks in a managed language.
Memory leaks are sneakily bad creatures. It’s easy to ignore them for a very long time, while they slowly destroy the application. With memory leaks, your memory consumption grows, creating GC pressure and performance problems. Finally, the program will just crash on an out-of-memory exception.
In this article, we will go over the most common reasons for memory leaks in .NET programs. All examples are in C#, but they are relevant to other languages.
دسترسی سریع به مقادیر خواص توسط Reflection.Emit
فرض کنید تعاریف کلاس User به صورت زیر است:
public class User { public int Id { set; get; } }
حال اگر یک متد پویا ایجاد کنیم که بجای هر بار Reflection جهت دریافت مقدار Id، خود متد get_Id را مستقیما صدا بزند، چه خواهد شد؟
پیاده سازی این نکته را در ادامه ملاحظه میکنید:
using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; namespace FastReflectionTests { /// <summary> /// کلاسی برای اندازه گیری زمان اجرای عملیات /// </summary> public class Benchmark : IDisposable { Stopwatch _watch; string _name; public static Benchmark Start(string name) { return new Benchmark(name); } private Benchmark(string name) { _name = name; _watch = new Stopwatch(); _watch.Start(); } public void Dispose() { _watch.Stop(); Console.WriteLine("{0} Total seconds: {1}" , _name, _watch.Elapsed.TotalSeconds); } } public class User { public int Id { set; get; } } class Program { public static Func<object, object> GetFastGetterFunc(string propertyName, Type ownerType) { var propertyInfo = ownerType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public); if (propertyInfo == null) return null; var getter = ownerType.GetMethod("get_" + propertyInfo.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (getter == null) return null; var dynamicGetterMethod = new DynamicMethod( name: "_", returnType: typeof(object), parameterTypes: new[] { typeof(object) }, owner: propertyInfo.DeclaringType, skipVisibility: true); var il = dynamicGetterMethod.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); // Load input to stack il.Emit(OpCodes.Castclass, propertyInfo.DeclaringType); // Cast to source type // نکته مهم در اینجا فراخوانی نهایی متد گت بدون استفاده از ریفلکشن است il.Emit(OpCodes.Callvirt, getter); //calls its get method if (propertyInfo.PropertyType.IsValueType) il.Emit(OpCodes.Box, propertyInfo.PropertyType);//box il.Emit(OpCodes.Ret); return (Func<object, object>)dynamicGetterMethod.CreateDelegate(typeof(Func<object, object>)); } static void Main(string[] args) { //تهیه لیستی از دادهها جهت آزمایش var list = new List<User>(); for (int i = 0; i < 1000000; i++) { list.Add(new User { Id = i }); } // دسترسی به اطلاعات لیست به صورت متداول از طریق ریفلکشن معمولی var idProperty = typeof(User).GetProperty("Id"); using (Benchmark.Start("Normal reflection")) { foreach (var item in list) { var id = idProperty.GetValue(item, null); } } // دسترسی از طریق روش سریع دستیابی به اطلاعات خواص var fastIdProperty = GetFastGetterFunc("Id", typeof(User)); using (Benchmark.Start("Fast Property")) { foreach (var item in list) { var id = fastIdProperty(item); } } } } }
از کلاس Benchmark برای نمایش زمان انجام عملیات دریافت مقادیر Id از یک لیست، به دو روش Reflection متداول و روش صدا زدن مستقیم متد get_Id استفاده شده است.
در متد GetFastGetterFunc، ابتدا به متد get_Id خاصیت Id دسترسی پیدا خواهیم کرد. سپس یک متد پویا ایجاد میکنیم تا این get_Id را مستقیما صدا بزند. حاصل کار را به صورت یک delegate بازگشت میدهیم. شاید عنوان کنید که در اینجا هم حداقل در ابتدای کار متد، یک Reflection اولیه وجود دارد. پاسخ این است که مهم نیست؛ چون در یک برنامه واقعی، تهیه delegates در زمان آغاز برنامه انجام شده و حاصل کش میشود. بنابراین در زمان استفاده نهایی، به هیچ عنوان با سربار Reflection مواجه نخواهیم بود.
خروجی آزمایش فوق بر روی سیستم معمولی من به صورت زیر است:
Normal reflection Total seconds: 2.0054177 Fast Property Total seconds: 0.0552056
چند پروژه که از این روش استفاده میکنند
Dapper
AutoMapper
fastJson
در سورس این کتابخانهها روشهای فراخوانی مستقیم متدهای set نیز پیاده سازی شدهاند که جهت تکمیل بحث میتوان به آنها مراجعه نمود.
ماخذ اصلی
این کشف و استفاده خاص، از اینجا شروع و عمومیت یافته است و پایه تمام کتابخانههایی است که پیشوند fast را به خود دادهاند:
2000% faster using dynamic method calls
کار با Json در پرس و جوهای SQL
تولید HTML از پرس و جوی های SQL
background-clip
is one of those properties I've known about for years, but rarely used. Maybe just a couple of times as part of a solution to a Stack Overflow question. Until last year, when I started creating my huge collection of sliders. Some of the designs I chose to reproduce were a bit more complex and I only had one element available per slider, which happened to be an input
element, meaning that I couldn't even use pseudo-elements on it. Even though that does work in certain browsers, the fact that it works is actually a bug and I didn't want to rely on that. All this meant I ended up using backgrounds, borders, and shadows a lot. I also learned a lot from doing that and this article shares some of those lessons.