Forwarded from DotNetZoom (محمد جواد ابراهیمی)
❇️ فرق Task.Run با Task.Factory.StartNew
در این سری پست های #پرسش_پاسخ قصد دارم بعضی از سوالاتی که دوستان میپرسند رو به همراه جواب هاشون برای شما به اشتراک بگذارم
🔸سوال:
فرق Task.Run با Task.Factory.StartNew چیه؟ از کدومشون باید استفاده کنیم؟
🔹پاسخ:
خود Task.Run پشت پرده از Task.Factory.StartNew استفاده میکنه و در واقع یه Wrapper روی اون هست که استفاده ازش رو ساده تر میکنه.
علتش اینه که Task.Factory.StartNew امضا (overload) های متفاوتی داره که کار با اون رو انعطاف پذیر تر میکنه که همین انعطاف پذیری بیشتر باعث شده کار باهاش پیچیده تر باشه. مثلا وجود آپشن های بیشتری از جمله TaskCreationOptions و TaskScheduler که اجازه میده سفارشی سازی بیشتری انجام بدیم.
همچنین با توجه به اینکه خروجی متد StartNew از نوع <Task<T هست، این نوع جنریک T درواقع خروجی همون delegate ایی که بهش پاس میدین. درنتیجه اگر delegate ورودی شما به متد StartNew، خودش از نوع Task باشه، خروجی نهایی متد StartNew میشه یک <Task<Task که در این حالت بایستی توسط متد Unwarp، اون تسک داخلی (inner task) رو بیرون بکشید و با اون کار بکنید
از این رو تیم دات نت به جهت جلوگیری و مخفی کردن این پیچیدگی ها اومده Task.Run رو برای سناریو های پرکاربرد ایجاد کرده که این پیچیدگی ها رو داخل خودش مخفی میکنه
جمع بندی اینکه همیشه از Task.Run به جای Task.Factory.StartNew استفاده کنید مگر اینکه نیاز به سفارشی سازی یا استفاده از حالت های خاص دارید (اون هم با آگاهی کامل) که توضیحش از حوصله این سوال خارجه
جهت اطلاعات بیشتر مطالعه لینک زیر کمکتون میکنه
▪️Task.Run vs Task.Factory.StartNew
🔸حالا که تا اینجای کار اومدید جا داره یه نکته دیگه هم بگم
علاوه بر روش های بالا 2 روش دیگه برای ساخت یک Task وجود داره.
1- نمونه سازی تسک توسط سازنده کلاس Task
2- استفاده از کلاس TaskCompletionSource
این دو روش کمتر عمومی بوده و معمولا نیاز نمیشه از این ها استفاده کنید. روش اول بسیار کم کاربرد هست و use-case های خاصی داره و باید با احتیاط و آگاهی ازش استفاده کنین.
وقتی شما توسط Task.Run یا Task.Factory.StartNew استفاده میکنید، یک تسک برای شما ساخته میشه و بلافاصله Start میشه. درنتیحه Task ایی که به دست شما میرسه از قبل start شده و فراخوانی مجدد متد Start روی اون، باعث وقوع Exception میشه
ولی وقتی توسط سازنده کلاس Task استفاده میکنید میتونین قبل از Start شدنش به اون نمونه ایجاد شده دسترسی پیدا کنین. و سپس باید به صورت دستی متد Start رو فراخوانی کنین تا Task اجرا بشه. هرچند فراخوانی دستی متد Start بدلیل Synchronization ایی که در پشت صحنه اعمال میشه (به دلیل جلوگیری از Start شدن همزمان توسط چندین Thread) دارای سربار هست
کلاس TaskCompletionSource اما مکانیزمش کلا فرق میکنه. این کلاس وظیفه ساخت "و مدیریت" چرخه حیات یک Task رو به عهده داره.
مثلا توسط متد های SetResult و SetException و SetCanceled (و نیز همین متد ها با پشوند TryXXX به جهت مدیریت همزمانی) این امکان رو به شما میده وضعیت تسک رو به یکی از این حالات تغییر بدید:
"کنسل شده" یا "خطا رخ داده" یا "تکمیل شده با موفقیت (به همراه نتیجه خروجی اون)"
از این روش معمولا برای تبدیل کد های قدیمی APM و EAP به TPL (روش جدید تر و توصیه شده مایکروسافت) استفاده میشه و یه use-case های خاصی که باید با احتیاط و آگاهی از استفاده بشه
اطلاعات بیشتر:
▪️Mechanisms for Creating Tasks
▪️The Nature of TaskCompletionSource
▪️The danger of TaskCompletionSource class
___________________
@DotNetZoom
در این سری پست های #پرسش_پاسخ قصد دارم بعضی از سوالاتی که دوستان میپرسند رو به همراه جواب هاشون برای شما به اشتراک بگذارم
🔸سوال:
فرق Task.Run با Task.Factory.StartNew چیه؟ از کدومشون باید استفاده کنیم؟
🔹پاسخ:
خود Task.Run پشت پرده از Task.Factory.StartNew استفاده میکنه و در واقع یه Wrapper روی اون هست که استفاده ازش رو ساده تر میکنه.
علتش اینه که Task.Factory.StartNew امضا (overload) های متفاوتی داره که کار با اون رو انعطاف پذیر تر میکنه که همین انعطاف پذیری بیشتر باعث شده کار باهاش پیچیده تر باشه. مثلا وجود آپشن های بیشتری از جمله TaskCreationOptions و TaskScheduler که اجازه میده سفارشی سازی بیشتری انجام بدیم.
همچنین با توجه به اینکه خروجی متد StartNew از نوع <Task<T هست، این نوع جنریک T درواقع خروجی همون delegate ایی که بهش پاس میدین. درنتیجه اگر delegate ورودی شما به متد StartNew، خودش از نوع Task باشه، خروجی نهایی متد StartNew میشه یک <Task<Task که در این حالت بایستی توسط متد Unwarp، اون تسک داخلی (inner task) رو بیرون بکشید و با اون کار بکنید
از این رو تیم دات نت به جهت جلوگیری و مخفی کردن این پیچیدگی ها اومده Task.Run رو برای سناریو های پرکاربرد ایجاد کرده که این پیچیدگی ها رو داخل خودش مخفی میکنه
جمع بندی اینکه همیشه از Task.Run به جای Task.Factory.StartNew استفاده کنید مگر اینکه نیاز به سفارشی سازی یا استفاده از حالت های خاص دارید (اون هم با آگاهی کامل) که توضیحش از حوصله این سوال خارجه
جهت اطلاعات بیشتر مطالعه لینک زیر کمکتون میکنه
▪️Task.Run vs Task.Factory.StartNew
🔸حالا که تا اینجای کار اومدید جا داره یه نکته دیگه هم بگم
علاوه بر روش های بالا 2 روش دیگه برای ساخت یک Task وجود داره.
1- نمونه سازی تسک توسط سازنده کلاس Task
2- استفاده از کلاس TaskCompletionSource
این دو روش کمتر عمومی بوده و معمولا نیاز نمیشه از این ها استفاده کنید. روش اول بسیار کم کاربرد هست و use-case های خاصی داره و باید با احتیاط و آگاهی ازش استفاده کنین.
وقتی شما توسط Task.Run یا Task.Factory.StartNew استفاده میکنید، یک تسک برای شما ساخته میشه و بلافاصله Start میشه. درنتیحه Task ایی که به دست شما میرسه از قبل start شده و فراخوانی مجدد متد Start روی اون، باعث وقوع Exception میشه
ولی وقتی توسط سازنده کلاس Task استفاده میکنید میتونین قبل از Start شدنش به اون نمونه ایجاد شده دسترسی پیدا کنین. و سپس باید به صورت دستی متد Start رو فراخوانی کنین تا Task اجرا بشه. هرچند فراخوانی دستی متد Start بدلیل Synchronization ایی که در پشت صحنه اعمال میشه (به دلیل جلوگیری از Start شدن همزمان توسط چندین Thread) دارای سربار هست
کلاس TaskCompletionSource اما مکانیزمش کلا فرق میکنه. این کلاس وظیفه ساخت "و مدیریت" چرخه حیات یک Task رو به عهده داره.
مثلا توسط متد های SetResult و SetException و SetCanceled (و نیز همین متد ها با پشوند TryXXX به جهت مدیریت همزمانی) این امکان رو به شما میده وضعیت تسک رو به یکی از این حالات تغییر بدید:
"کنسل شده" یا "خطا رخ داده" یا "تکمیل شده با موفقیت (به همراه نتیجه خروجی اون)"
از این روش معمولا برای تبدیل کد های قدیمی APM و EAP به TPL (روش جدید تر و توصیه شده مایکروسافت) استفاده میشه و یه use-case های خاصی که باید با احتیاط و آگاهی از استفاده بشه
اطلاعات بیشتر:
▪️Mechanisms for Creating Tasks
▪️The Nature of TaskCompletionSource
▪️The danger of TaskCompletionSource class
___________________
@DotNetZoom
Microsoft News
Task.Run vs Task.Factory.StartNew
In .NET 4, Task.Factory.StartNew was the primary method for scheduling a new task. Many overloads provided for a highly configurable mechanism, enabling setting options, passing in arbitrary state, enabling cancellation, and even controlling scheduling behaviors. …
Forwarded from DotNetZoom (محمد جواد ابراهیمی)
❇️ تفاوت Event و Delegate و مشکل نشتی حافظه (Memory Leaks) در کار با Event ها
در این پست ابتدا به تفاوت های event و delegate می پردازیم و سپس علت مشکل نشتی حافظه رو به هنگام استفاده از اون ها بررسی میکنیم (سوالی که ممکنه بعضا توی مصاحبه باهاش برخورد کرده باشین)
🔸در ابتدا باید بگم که این دو خیلی شبیه به هم هستند
1- هر دو میتونن باعث memory leak بشن
2- هر دو این امکان رو دارن که با =+ و =- بشه چندتا متد رو بهشون اضافه یا کم کرد
3- هر دو موقع raise شدن (اجرا شدن)، تمام متد های ثبت شده داخل خودشون رو فراخوانی میکنن
🔹و اما تفاوت های اونها چیه؟
در واقع event یک abstraction بر روی delegate هست که یک سری محدودیت ها (بهتره بگیم محافظت ها) رو روش اعمال میکنه
1- اجازه نمیده event رو ریست کنین (یعنی فقط اجازه میده با += و -= متدی بهش اضافه یا کم کنین ولی اجازه نمیده که با = مقدارش رو ریست کنین)
2- اون event رو فقط از طریق داخل کلاس شامل شوندش قابل فراخوانی میکنه یعنی از بیرون کسی نمیتونه اون event رو فراخوانی کنه
🔸بررسی مشکل نشتی حافظه در Event و Delegate
احتمالا خیلی جا ها دیدید یا شنیدید که میگن event ها میتونن باعث نشتی حافظه بشن. اما این مورد محدود به event نیست؛ برای delegate ها هم میتونه اتفاق بیافته. حتی برای یک شی استاتیک هم میتونه اتفاق بیافته. در واقع علت اصلی این مشکل مربوط به باقی ماندن رفرنس اشیای «بلا استفاده» هست
فرض کنین یه کلاس static داریم که داخلش یه لیست static هست. طبیعتا طول عمر این لیست به دلیل static بودن تا پایان عمر application باقی خواهد ماند، در نتیجه GC (مخفف Garbage Collector)، اون لیست رو Dispose نمیکنه
حالا اگر در طول برنامه اشیایی رو درون اون لیست Add کنیم عملا چون رفرنس اون اشیا داخل لیست باقی میمونن، اون اشیا هم تا پایان عمر برنامه Dispose نمیشن (حتی اگه دیگه با اون اشیا کاری نداشته باشیم) و همین عامل هست که باعث Memory Leak میشه
حالا مشابه همین اتفاق میتونه برای event ها و delegate ها هم بیافته
در واقع وقتی متدی از یک شی رو به یک event یا delegate (مانند Action و Func) توسط = یا =+ نسبت میدین، رفرنس اون شی هم Capture میشه، در نتیجه تا پایان عمر اون event یا delegate مربوطه، اون اشیاء هم باقی میمونن و Dispose نمیشن
🔹برای رفع این مشکل راه حل های مختلفی هست
1️⃣ استفاده از -= برای حذف کردن رفرنس (unsubscribe کردن) اون متد از event یا delegate مربوطه
2️⃣ استفاده از الگوی Weak Reference Pattern که توسط کلاس WeakEventHandler دات نت پیاده سازی میشه
3️⃣ استفاده از الگوی Event Aggregator Pattern که اون هم به نوعی از Weak Reference استفاده میکنه و داخل کتابخونه Prism زیاد ازش استفاده شده
و روش های دیگه که خارج از توضیح این پست هست
🔰جهت اطلاعات بیشتر و روش های جلوگیری از نشتی حافظه پیشنهاد میکنم مقالات زیر رو مطالعه کنین
✔️5 Techniques to avoid Memory Leaks by Events in C# .NET you should know
✔️Understanding and Avoiding Memory Leaks with Event Handlers and Event Aggregators
✔️Memory Leak in C#
✔️Are you afraid of event handlers because of C# memory leak?
✔️Events: Demystifying Common Memory Leaks
✔️Weak Event Patterns
_________________
@DotNetZoom
در این پست ابتدا به تفاوت های event و delegate می پردازیم و سپس علت مشکل نشتی حافظه رو به هنگام استفاده از اون ها بررسی میکنیم (سوالی که ممکنه بعضا توی مصاحبه باهاش برخورد کرده باشین)
🔸در ابتدا باید بگم که این دو خیلی شبیه به هم هستند
1- هر دو میتونن باعث memory leak بشن
2- هر دو این امکان رو دارن که با =+ و =- بشه چندتا متد رو بهشون اضافه یا کم کرد
3- هر دو موقع raise شدن (اجرا شدن)، تمام متد های ثبت شده داخل خودشون رو فراخوانی میکنن
🔹و اما تفاوت های اونها چیه؟
در واقع event یک abstraction بر روی delegate هست که یک سری محدودیت ها (بهتره بگیم محافظت ها) رو روش اعمال میکنه
1- اجازه نمیده event رو ریست کنین (یعنی فقط اجازه میده با += و -= متدی بهش اضافه یا کم کنین ولی اجازه نمیده که با = مقدارش رو ریست کنین)
2- اون event رو فقط از طریق داخل کلاس شامل شوندش قابل فراخوانی میکنه یعنی از بیرون کسی نمیتونه اون event رو فراخوانی کنه
🔸بررسی مشکل نشتی حافظه در Event و Delegate
احتمالا خیلی جا ها دیدید یا شنیدید که میگن event ها میتونن باعث نشتی حافظه بشن. اما این مورد محدود به event نیست؛ برای delegate ها هم میتونه اتفاق بیافته. حتی برای یک شی استاتیک هم میتونه اتفاق بیافته. در واقع علت اصلی این مشکل مربوط به باقی ماندن رفرنس اشیای «بلا استفاده» هست
فرض کنین یه کلاس static داریم که داخلش یه لیست static هست. طبیعتا طول عمر این لیست به دلیل static بودن تا پایان عمر application باقی خواهد ماند، در نتیجه GC (مخفف Garbage Collector)، اون لیست رو Dispose نمیکنه
حالا اگر در طول برنامه اشیایی رو درون اون لیست Add کنیم عملا چون رفرنس اون اشیا داخل لیست باقی میمونن، اون اشیا هم تا پایان عمر برنامه Dispose نمیشن (حتی اگه دیگه با اون اشیا کاری نداشته باشیم) و همین عامل هست که باعث Memory Leak میشه
حالا مشابه همین اتفاق میتونه برای event ها و delegate ها هم بیافته
در واقع وقتی متدی از یک شی رو به یک event یا delegate (مانند Action و Func) توسط = یا =+ نسبت میدین، رفرنس اون شی هم Capture میشه، در نتیجه تا پایان عمر اون event یا delegate مربوطه، اون اشیاء هم باقی میمونن و Dispose نمیشن
🔹برای رفع این مشکل راه حل های مختلفی هست
1️⃣ استفاده از -= برای حذف کردن رفرنس (unsubscribe کردن) اون متد از event یا delegate مربوطه
2️⃣ استفاده از الگوی Weak Reference Pattern که توسط کلاس WeakEventHandler دات نت پیاده سازی میشه
3️⃣ استفاده از الگوی Event Aggregator Pattern که اون هم به نوعی از Weak Reference استفاده میکنه و داخل کتابخونه Prism زیاد ازش استفاده شده
و روش های دیگه که خارج از توضیح این پست هست
🔰جهت اطلاعات بیشتر و روش های جلوگیری از نشتی حافظه پیشنهاد میکنم مقالات زیر رو مطالعه کنین
✔️5 Techniques to avoid Memory Leaks by Events in C# .NET you should know
✔️Understanding and Avoiding Memory Leaks with Event Handlers and Event Aggregators
✔️Memory Leak in C#
✔️Are you afraid of event handlers because of C# memory leak?
✔️Events: Demystifying Common Memory Leaks
✔️Weak Event Patterns
_________________
@DotNetZoom
Michael's Coding Spot
5 Techniques to avoid Memory Leaks by Events in C# .NET you should know
Event registrations in C# (and .NET in general) are the most common cause of memory leaks. At least from my experience. In fact, I saw so much memory leaks from events that seeing += in code immediately makes me suspicious.
Forwarded from DotNetZoom (محمد جواد ابراهیمی)
✅ مفهوم Expression Tree در دات نت
میشه گفت یکی از advanced ترین قسمت های دات نت، مفهوم Expression Tree و کلاس Expression هست که یه جورایی قلب IQueryable رو هم تشکیل میده
شاید نهایت استفاده افراد، کار با <<Expression<Func برای شرط های predicate بر روی متد Where و یا selector برای متد Select باشه
ولی Expression خیلی بزرگتر از اینهاست
🔸درواقع مفهوم Expression Tree به مجموعه از از node ها در قالب یک ساختار درختی گفته میشه که هر node اون، خود یک Expression هست. اما خود Expression چیه؟
درواقع هر Expression یک operation (عملیات) برنامه نویسی رو بیان میکنه. توسط کلاس Expression در دات نت میتوان برای هر عملیات برنامه نویسی یک expression ساخت.
🔹به عنوان مثال:
- تعریف یک variable (متغیر)، constant یا parameter (پارامتر ورودی متد)
- انتصاب یک مقدار به یک variable یا parameter
- جمع، تفریق، ضرب، تقسیم و... کردن دو مقدار
- تعریف یک شرط (if/else) یا سویچ (switch) منطقی
- تعریف یک حلقه (for یا while)
- بازگرداندن (return کردن) خروجی متد
- فراخوانی یک متد، پاس دادن پارامتر های ورودی و گرفتن مقدار خروجی
- و... اکثر کار هایی که شما توسط کد نویسی میتونین انجام بدین
🔸فرق expression با کد نویسی معمولی برای operation های برنامه نویسی اینه که توسط Expression میتوان یک ساختار (data structure) قابل توصیف برای کد ها ایجاد کرد.
در نتیجه میتوان از روی این ساختار قابل توصیف، کار های متفاوت و خلاقانه ای انجام داد. مثلا میشه از روی ساختار کد هامون Transpilation انجام بدیم و کوئری (مثلا SQL) معادل اون رو تولید کرد.
🔹در واقع هنگامی که شما یک عبارت lambda رو به یکی از متد های linq که ورودی <Expression<Func داره پاس میدین، پشت صحنه به هنگام Compile یک LambdaExpression از روی عبارت lambda شما ساخته میشه و اون هست که به متد شما پاس داده میشه.
چرا؟ چون که ساختار کد شما رو لازم داره تا بتونه از روی اون Transpilation انجام بده و کوئری (مثلا SQL) معادل اون رو تولید کنه. (این مثال رو ببینید)
🔸یا حتی میتوان به کمک Transpilation، از روی یک expression یک عبارت readable (خوانا) جهت توصیف کاری که قراره انجام بده تولید کرد. همانند کاری که کتابخانه ReadableExpressions کرده و توسط افزونه ویژوال استادیو ReadableExpressions.Visualizers این امکان رو میده که به هنگام دیباگ بتونین یک readable view از روی expression هاتون ببینید
🔹کار دیگه ای که توسط Expression میشه انجام داد. تولید کد IL (مخفف Intermediate Language) از روی اون هست. مثلا شما نمیتونین توسط Reflection حتی، یک متد جدید (شامل مجمومه ای از operation ها) ایجاد کنین ولی توسط Expression میتونین به جای اینکه کد شما به هنگام compile تبدیل به IL بشه، اون رو به هنگام run-time (در زمان اجرای برنامه) از روی همون expression (که یک ساختار قابل توصیف از یک تیکه کد هست) به کد IL تبدیل کنین یا اصطلاحات Emit کنین (بیرون بدین)
در نتیجه میتونین به هنگام run-time کد جدید تولید کنین و این همون تکنیکی هست که کتابخانه های Object Mapper از جمله AutoMapper و Mapster و... از اون استفاده میکنن
🔸گفتم Emit، جا داره از Reflection.Emiit هم یادی بکنیم که پایه ای ترین روش برای تولید کد IL در زمان run-time هست و میشه Expression رو به عنوان یک wrapper روی Reflection.Emit محسوب کرد که کار با اون رو ساده تر میکنه. هرچند کار هایی میشه با Reflection.Emit انجام داد که توسط Expression Tree نمیشه انجام داد (و بلعکس) پس اینجا به هیچ عنوان جایگزین هم نیستند بلکه فقط توی تولید کد IL وجه مشترک دارند.
🔰 جمع بندی
قابلیت Expression Tree یک قابلیت پیشرفته هست و نیاز اکثر افراد نمیشه ولی مزایای غیر قابل چشم پوشی ایی رو به ما میده که حرفه ای ها میتونین کار جالبی باهاش بکنن. توسط این قابلیت که یکی از جذاب ترین امکانات دات نت هست میتونین کار های جالبی انجام بدین از جمله:
1️⃣ گردش روی node ها و فهمیدن ساختار کد (MetaProgramming)
2️⃣ ترجمه کد ها به یک زبان دیگر (Transpilation)
3️⃣ تولید کد IL از روی اون (Code Generation)
💎در آخر یکی از بهترین مقالاتی که این مفهوم رو به خوبی به همراه مثال توضیح داده مقاله زیر هست که پیشنهاد میکنم حتما بخونین
https://tyrrrz.me/blog/expression-trees
____________________
@DotNetZoom
میشه گفت یکی از advanced ترین قسمت های دات نت، مفهوم Expression Tree و کلاس Expression هست که یه جورایی قلب IQueryable رو هم تشکیل میده
شاید نهایت استفاده افراد، کار با <<Expression<Func برای شرط های predicate بر روی متد Where و یا selector برای متد Select باشه
ولی Expression خیلی بزرگتر از اینهاست
🔸درواقع مفهوم Expression Tree به مجموعه از از node ها در قالب یک ساختار درختی گفته میشه که هر node اون، خود یک Expression هست. اما خود Expression چیه؟
درواقع هر Expression یک operation (عملیات) برنامه نویسی رو بیان میکنه. توسط کلاس Expression در دات نت میتوان برای هر عملیات برنامه نویسی یک expression ساخت.
🔹به عنوان مثال:
- تعریف یک variable (متغیر)، constant یا parameter (پارامتر ورودی متد)
- انتصاب یک مقدار به یک variable یا parameter
- جمع، تفریق، ضرب، تقسیم و... کردن دو مقدار
- تعریف یک شرط (if/else) یا سویچ (switch) منطقی
- تعریف یک حلقه (for یا while)
- بازگرداندن (return کردن) خروجی متد
- فراخوانی یک متد، پاس دادن پارامتر های ورودی و گرفتن مقدار خروجی
- و... اکثر کار هایی که شما توسط کد نویسی میتونین انجام بدین
🔸فرق expression با کد نویسی معمولی برای operation های برنامه نویسی اینه که توسط Expression میتوان یک ساختار (data structure) قابل توصیف برای کد ها ایجاد کرد.
در نتیجه میتوان از روی این ساختار قابل توصیف، کار های متفاوت و خلاقانه ای انجام داد. مثلا میشه از روی ساختار کد هامون Transpilation انجام بدیم و کوئری (مثلا SQL) معادل اون رو تولید کرد.
🔹در واقع هنگامی که شما یک عبارت lambda رو به یکی از متد های linq که ورودی <Expression<Func داره پاس میدین، پشت صحنه به هنگام Compile یک LambdaExpression از روی عبارت lambda شما ساخته میشه و اون هست که به متد شما پاس داده میشه.
چرا؟ چون که ساختار کد شما رو لازم داره تا بتونه از روی اون Transpilation انجام بده و کوئری (مثلا SQL) معادل اون رو تولید کنه. (این مثال رو ببینید)
🔸یا حتی میتوان به کمک Transpilation، از روی یک expression یک عبارت readable (خوانا) جهت توصیف کاری که قراره انجام بده تولید کرد. همانند کاری که کتابخانه ReadableExpressions کرده و توسط افزونه ویژوال استادیو ReadableExpressions.Visualizers این امکان رو میده که به هنگام دیباگ بتونین یک readable view از روی expression هاتون ببینید
🔹کار دیگه ای که توسط Expression میشه انجام داد. تولید کد IL (مخفف Intermediate Language) از روی اون هست. مثلا شما نمیتونین توسط Reflection حتی، یک متد جدید (شامل مجمومه ای از operation ها) ایجاد کنین ولی توسط Expression میتونین به جای اینکه کد شما به هنگام compile تبدیل به IL بشه، اون رو به هنگام run-time (در زمان اجرای برنامه) از روی همون expression (که یک ساختار قابل توصیف از یک تیکه کد هست) به کد IL تبدیل کنین یا اصطلاحات Emit کنین (بیرون بدین)
در نتیجه میتونین به هنگام run-time کد جدید تولید کنین و این همون تکنیکی هست که کتابخانه های Object Mapper از جمله AutoMapper و Mapster و... از اون استفاده میکنن
🔸گفتم Emit، جا داره از Reflection.Emiit هم یادی بکنیم که پایه ای ترین روش برای تولید کد IL در زمان run-time هست و میشه Expression رو به عنوان یک wrapper روی Reflection.Emit محسوب کرد که کار با اون رو ساده تر میکنه. هرچند کار هایی میشه با Reflection.Emit انجام داد که توسط Expression Tree نمیشه انجام داد (و بلعکس) پس اینجا به هیچ عنوان جایگزین هم نیستند بلکه فقط توی تولید کد IL وجه مشترک دارند.
🔰 جمع بندی
قابلیت Expression Tree یک قابلیت پیشرفته هست و نیاز اکثر افراد نمیشه ولی مزایای غیر قابل چشم پوشی ایی رو به ما میده که حرفه ای ها میتونین کار جالبی باهاش بکنن. توسط این قابلیت که یکی از جذاب ترین امکانات دات نت هست میتونین کار های جالبی انجام بدین از جمله:
1️⃣ گردش روی node ها و فهمیدن ساختار کد (MetaProgramming)
2️⃣ ترجمه کد ها به یک زبان دیگر (Transpilation)
3️⃣ تولید کد IL از روی اون (Code Generation)
💎در آخر یکی از بهترین مقالاتی که این مفهوم رو به خوبی به همراه مثال توضیح داده مقاله زیر هست که پیشنهاد میکنم حتما بخونین
https://tyrrrz.me/blog/expression-trees
____________________
@DotNetZoom
Oleksii Holub
Working with Expression Trees in C# • Oleksii Holub
Expression trees is an obscure, although very interesting feature in .NET. Most people probably think of it as something synonymous with object-relational mapping frameworks, but despite being its most common use case, it's not the only one. There are a…
بررسی نقش کلمه کلیدی await در برنامه نویسی Async در دات نت و ASP NET Core
https://youtu.be/4sscBQdVrfI
https://youtu.be/4sscBQdVrfI
Forwarded from DotNetZoom (محمد جواد ابراهیمی)
✅ بهبود SEO سایت های AspNet Core توسط کتابخانه SeoTags به کمک قابلیت Structred Data و JSON-LD
قابلیت Structured Data یکی از مباحث پیشرفته SEO هست که با تعریف ساختار صفحه به موتور های جستجو کمک میکنه محتوای صفحه شما رو بهتر متوجه بشن و نمایش بدن. نمونه نمایش نتایج در صفحه سرچ گوگل این موضوع رو میتونین از این لینک مشاهده کنین. همانطور که میبینین بعضی موارد به صورت rich result نمایش داده میشوند.
گوگل داکیومنت کاملی در مورد پیاده سازی Structured Data داره که از این لینک میتونین مشاهده کنین.
پیاده سازی این قابلیت توسط یکی از سه روش زیر انجام میشه
1- روش JSON-LD
2- روش Microdata
3- روش RDFa
روش اول یعنی JSON-LD روش پیشنهادی گوگل هست و در اون محتوای صفحه به صورت json در قالب استاندارد Schema.org درون یک تگ script از نوع application/ld+json تعریف میشه. که در این لینک میتونین نمونه پیاده سازیش رو برای یک product مشاهده کنین.
در روش های Microdata و RDFa هم محتوای صفحه در قالب attribute هایی بر روی تگ های html نشانه گذاری میشن.
داکیومنت گوگل یک قسمت از نحوه پیاده سازی این مورد برای مثال های پرکاربرد از جمله Article و Product و Book و ... نیز ارائه کرده.
حالا کتابخانه SeoTags از JSON-LD هم پشتیبانی میکنه و علاوه بر تولید تمام تگ های SEO برای سایت شما، محتوای JSON-LD رو هم خروجی میده.
داکیومنت استفاده از این کتابخانه برای تولید تگ های meta و link و... در اینجا مشاهده کنید.
و نمونه استفاده از قابلیت JSON-LD رو هم در اینجا و اینجا مشاهده کنید.
https://mjebrahimi.github.io/SeoTags/
__________________
@DotNetZoom
قابلیت Structured Data یکی از مباحث پیشرفته SEO هست که با تعریف ساختار صفحه به موتور های جستجو کمک میکنه محتوای صفحه شما رو بهتر متوجه بشن و نمایش بدن. نمونه نمایش نتایج در صفحه سرچ گوگل این موضوع رو میتونین از این لینک مشاهده کنین. همانطور که میبینین بعضی موارد به صورت rich result نمایش داده میشوند.
گوگل داکیومنت کاملی در مورد پیاده سازی Structured Data داره که از این لینک میتونین مشاهده کنین.
پیاده سازی این قابلیت توسط یکی از سه روش زیر انجام میشه
1- روش JSON-LD
2- روش Microdata
3- روش RDFa
روش اول یعنی JSON-LD روش پیشنهادی گوگل هست و در اون محتوای صفحه به صورت json در قالب استاندارد Schema.org درون یک تگ script از نوع application/ld+json تعریف میشه. که در این لینک میتونین نمونه پیاده سازیش رو برای یک product مشاهده کنین.
در روش های Microdata و RDFa هم محتوای صفحه در قالب attribute هایی بر روی تگ های html نشانه گذاری میشن.
داکیومنت گوگل یک قسمت از نحوه پیاده سازی این مورد برای مثال های پرکاربرد از جمله Article و Product و Book و ... نیز ارائه کرده.
حالا کتابخانه SeoTags از JSON-LD هم پشتیبانی میکنه و علاوه بر تولید تمام تگ های SEO برای سایت شما، محتوای JSON-LD رو هم خروجی میده.
داکیومنت استفاده از این کتابخانه برای تولید تگ های meta و link و... در اینجا مشاهده کنید.
و نمونه استفاده از قابلیت JSON-LD رو هم در اینجا و اینجا مشاهده کنید.
https://mjebrahimi.github.io/SeoTags/
__________________
@DotNetZoom
GitHub
GitHub - mjebrahimi/SeoTags: 🚀 SeoTags generates All SEO Tags you need such as meta, link, Twitter card (twitter:), Open Graph…
🚀 SeoTags generates All SEO Tags you need such as meta, link, Twitter card (twitter:), Open Graph (for Facebook) (og:), and JSON-LD schema (structured data). - mjebrahimi/SeoTags
Forwarded from کدهک
در زبان سی شارپ کامپایلر Roslyn وظیفه ی Parse کردن و اعلام خطاهای Syntax را به عده دارد. در ادامه بهینه سازی انجام میدهد و کد میانی یا Intermediate Language را تولید می کند. این همان فایل dll یا exe برنامه ی شماست.
سپس در هنگام اجرا بسته به اینکه از چه پردازنده ای استفاده می کنید Just In Time Compiler دات نت که به RyuJIT معروف است شروع به کار میکند و در لحظه اجرای برنامه کد ماشین را تولید می کند.
استفاده از JIT کمک می کند برنامه به سخت افزار وابستگی مستقیم نداشته باشد و مجبور نباشیم برای هر سیستم عامل و سخت افزار جدا فایل جداگانه ای تولید کنیم.
در بعضی برنامه ها برای بالا بردن پرفورمنس از دستورات برداری استفاده میشود. چنانچه پردازنده از این دستورات پشتیبانی نکند برنامه خیلی کندتر از حالت بدون بردار اجرا میشود.
یکی از مشکلاتی که RyuJIT حل میکند بهینه سازی SIMD است. این ابزار می تواند بر اساس قابلیت های پردازنده کدهای برداری را به کدهای معمولی تبدیل کند تا حداکثر پرفورمنس بدست آید.
سپس در هنگام اجرا بسته به اینکه از چه پردازنده ای استفاده می کنید Just In Time Compiler دات نت که به RyuJIT معروف است شروع به کار میکند و در لحظه اجرای برنامه کد ماشین را تولید می کند.
استفاده از JIT کمک می کند برنامه به سخت افزار وابستگی مستقیم نداشته باشد و مجبور نباشیم برای هر سیستم عامل و سخت افزار جدا فایل جداگانه ای تولید کنیم.
در بعضی برنامه ها برای بالا بردن پرفورمنس از دستورات برداری استفاده میشود. چنانچه پردازنده از این دستورات پشتیبانی نکند برنامه خیلی کندتر از حالت بدون بردار اجرا میشود.
یکی از مشکلاتی که RyuJIT حل میکند بهینه سازی SIMD است. این ابزار می تواند بر اساس قابلیت های پردازنده کدهای برداری را به کدهای معمولی تبدیل کند تا حداکثر پرفورمنس بدست آید.
Forwarded from DotNetZoom (Ali Abdolmaleki)
❇️ نکاتی در مورد کار با PDF در دات نت و برترین کتابخانه های آن
کتابخونه های کار با pdf به 2 دسته کلی تقسیم میشن
🔸دسته اول کتابخونه هایی هستند که باهاشون میشه فایل های PDF رو خوند، محتواشو Extract کرد، Edit کرد و یا فایل جدید ساخت
از معروف ترین این کتابخونه ها میشه به ترتیب به موارد زیر اشاره کرد
✔️iTextSharp
✔️iTextSharp.LGPLv2.Core
✔️itext7
✔️PdfSharpCore
معروف ترین شون iTextSharp هست که فقط NET Framework Full. رو پشتیبانی میکنه اما وحید نصیری یه نسخه port شده ازش رو برای NET Core. رو براش درست کرده به نام iTextSharp.LGPLv2.Core
همچنین کتابخونه itext7 که توسط سازنده iTextSharp توسعه داده شده و به عنوان نسخه بعدی iTextSharp و با پشتیبانی از NET Core. اون رو توسعه داده و توصیه میکنه از itext7 استفاده کنین.
🔹دسته دوم کتابخونه هایی هستند که میتونن محتوای یه صفحه html (شامل المان ها و css ها و ...) رو به صورت PDF رندر کنن و خروجی PDF ازشون بگیرن
از جمله معروف ترین این کتابخونه ها میشه به ترتیب به موارد زیر اشاره کرد
✔️DinkToPdf
✔️itext7.pdfhtml
✔️Rotativa.AspNetCore
✔️Wkhtmltopdf.NetCore
طرز کار همشونم به این صورته که اینا معمولا wrapper ایی بر روی کتابخانه wkhtmltopdf هستند که کارش Render کردن خروجی html به pdf هست و پشت صحنه هم از موتور Qt WebKit استفاده میکنن که یک Browser Engine سورس باز هست
🔸اکثر مواقع نیاز برنامه نویسا همین دسته دوم هست. معمولا میخوان از گزارشاتشون خروجی pdf بگیرن که دسته دوم گزینه راحت تری هست چرا که اینجا ما دیگه با یه صفحه html+css سرو کار داریم و خیلی راحت میتونیم هر فرم و جدولی رو که بخوایم طراحی کنیم و وقتی از خروجی html ایی اون مطمئن شدیم اون رو به pdf تبدیل کنیم
دسته اول معمولا کاربرد خاص تری دارند. مثلا اگه بخواین فایل pdf تون رو بخونین، محتواش رو پردازش یا ویرایش کنین یا مثلا ساخت صفحاتتون رو خیلی سفارشی سازی کنین باید از کتابخونه های دسته اول استفاده کنین
یه سری کتابخونه قدرتمند دیگه هم هستند مثل Aspose و Syncfusion ولی چون اونا پولی هستند و نسخه رایگانشون محدودیت داره تو لیست نیاوردمشون
_______________
@DotNetZoom
کتابخونه های کار با pdf به 2 دسته کلی تقسیم میشن
🔸دسته اول کتابخونه هایی هستند که باهاشون میشه فایل های PDF رو خوند، محتواشو Extract کرد، Edit کرد و یا فایل جدید ساخت
از معروف ترین این کتابخونه ها میشه به ترتیب به موارد زیر اشاره کرد
✔️iTextSharp
✔️iTextSharp.LGPLv2.Core
✔️itext7
✔️PdfSharpCore
معروف ترین شون iTextSharp هست که فقط NET Framework Full. رو پشتیبانی میکنه اما وحید نصیری یه نسخه port شده ازش رو برای NET Core. رو براش درست کرده به نام iTextSharp.LGPLv2.Core
همچنین کتابخونه itext7 که توسط سازنده iTextSharp توسعه داده شده و به عنوان نسخه بعدی iTextSharp و با پشتیبانی از NET Core. اون رو توسعه داده و توصیه میکنه از itext7 استفاده کنین.
🔹دسته دوم کتابخونه هایی هستند که میتونن محتوای یه صفحه html (شامل المان ها و css ها و ...) رو به صورت PDF رندر کنن و خروجی PDF ازشون بگیرن
از جمله معروف ترین این کتابخونه ها میشه به ترتیب به موارد زیر اشاره کرد
✔️DinkToPdf
✔️itext7.pdfhtml
✔️Rotativa.AspNetCore
✔️Wkhtmltopdf.NetCore
طرز کار همشونم به این صورته که اینا معمولا wrapper ایی بر روی کتابخانه wkhtmltopdf هستند که کارش Render کردن خروجی html به pdf هست و پشت صحنه هم از موتور Qt WebKit استفاده میکنن که یک Browser Engine سورس باز هست
🔸اکثر مواقع نیاز برنامه نویسا همین دسته دوم هست. معمولا میخوان از گزارشاتشون خروجی pdf بگیرن که دسته دوم گزینه راحت تری هست چرا که اینجا ما دیگه با یه صفحه html+css سرو کار داریم و خیلی راحت میتونیم هر فرم و جدولی رو که بخوایم طراحی کنیم و وقتی از خروجی html ایی اون مطمئن شدیم اون رو به pdf تبدیل کنیم
دسته اول معمولا کاربرد خاص تری دارند. مثلا اگه بخواین فایل pdf تون رو بخونین، محتواش رو پردازش یا ویرایش کنین یا مثلا ساخت صفحاتتون رو خیلی سفارشی سازی کنین باید از کتابخونه های دسته اول استفاده کنین
یه سری کتابخونه قدرتمند دیگه هم هستند مثل Aspose و Syncfusion ولی چون اونا پولی هستند و نسخه رایگانشون محدودیت داره تو لیست نیاوردمشون
_______________
@DotNetZoom
Telegram
Attach Files
Forwarded from DotNetZoom (محمد جواد ابراهیمی)
✅ معرفی ویژگی Records در C# 9.0: کار با دادههای تغییر ناپذیر
🔸 کار کردن با دادههای تغییر ناپذیر بسیار قدرتمند است، اغلب منجر به باگهای کمتری میشود، و شما را مجبور میکند تا اشیا را تبدیل به اشیای جدید کنید به جای اینکه اشیای موجود را اصلاح کنید. توسعه دهندگان #F به این عادت کردهاند، زیرا #F همه چیز را به طور پیشفرض به عنوان تغییرناپذیر در نظر میگیرد. حالا شما انواع تغییر ناپذیر را در C# ۹.۰ نیز دارید، یا به اصطلاح انواع record نامیده میشود. Records کار با دادههای تغییر ناپذیر در #C را برای شما آسانتر میکند.
❇️ از طریق لینک زیر میتوانید ترجمه مقالهای از Thomas Claudius Huber که به بررسی این ویژگی و جزییات بیشتر پرداخته مطالعه کنید:
#سپهر_اسلامی
https://vrgl.ir/1zp5a
_____________
@DotNetZoom
🔸 کار کردن با دادههای تغییر ناپذیر بسیار قدرتمند است، اغلب منجر به باگهای کمتری میشود، و شما را مجبور میکند تا اشیا را تبدیل به اشیای جدید کنید به جای اینکه اشیای موجود را اصلاح کنید. توسعه دهندگان #F به این عادت کردهاند، زیرا #F همه چیز را به طور پیشفرض به عنوان تغییرناپذیر در نظر میگیرد. حالا شما انواع تغییر ناپذیر را در C# ۹.۰ نیز دارید، یا به اصطلاح انواع record نامیده میشود. Records کار با دادههای تغییر ناپذیر در #C را برای شما آسانتر میکند.
❇️ از طریق لینک زیر میتوانید ترجمه مقالهای از Thomas Claudius Huber که به بررسی این ویژگی و جزییات بیشتر پرداخته مطالعه کنید:
#سپهر_اسلامی
https://vrgl.ir/1zp5a
_____________
@DotNetZoom
ویرگول
C# 9.0: Records - کار با دادههای تغییر ناپذیر کلاسها
از ویژگیهای جدید سی شارپ ، ویژگی record را بررسی و معرفی میکنیم
دسترسی آسان و سریع به تنظیمات درون سیستم و اپلیکیشن از بایدهای یک فریم ورک تحت وب است. در ASP NET Core می توانید از IConfiguration برای اینکار استفاده کنید.
https://youtu.be/2EwUOB6IPMw
https://youtu.be/2EwUOB6IPMw
Forwarded from DotNetZoom (محمد جواد ابراهیمی)
✅ ساخت چت روم با Blazor Web Assembly و SignalR قسمت دوم: ساخت کلاینت
در این قسمت قصد داریم به ادامه ساخت چت روم بوسیله Blazor web assembly بپردازیم. در این مقاله به مباحثی مانند: SignalR Client
پیاده سازی لاگین و رجیستر کاربر
نحوه استفاده از local storage برای ذخیره و خواندن اطلاعاتی مانند JWT Token
نحوه تنظیم SignalR Client برای استفاده از JWT Token
هندل کردن رویداد های SignalR سمت Client
نحوه ارتباط با web api و فرستادن JWT Token به آن
آشنایی با تایمر
جداسازی کد از UI در Blazor
مبحث Dependecy Injection
استفاده از Toaster Component در Blazor
آشنایی با event های پرکاربرد در Blazor
خواهیم پرداخت
#بابک_طارمی
https://vrgl.ir/kByMS
_________
@DotNetZoom
در این قسمت قصد داریم به ادامه ساخت چت روم بوسیله Blazor web assembly بپردازیم. در این مقاله به مباحثی مانند: SignalR Client
پیاده سازی لاگین و رجیستر کاربر
نحوه استفاده از local storage برای ذخیره و خواندن اطلاعاتی مانند JWT Token
نحوه تنظیم SignalR Client برای استفاده از JWT Token
هندل کردن رویداد های SignalR سمت Client
نحوه ارتباط با web api و فرستادن JWT Token به آن
آشنایی با تایمر
جداسازی کد از UI در Blazor
مبحث Dependecy Injection
استفاده از Toaster Component در Blazor
آشنایی با event های پرکاربرد در Blazor
خواهیم پرداخت
#بابک_طارمی
https://vrgl.ir/kByMS
_________
@DotNetZoom
ویرگول
ساخت چت روم با Blazor Web Assembly و SignalR قسمت دوم: ساخت کلاینت
در این مقاله قصد داریم به ادامه ساخت چت روم با ASP Net Core Web API و Blazor Web Assembly بپردازیم.