⚡ استفاده حرفهای از ConfigureAwait(false) در async/await
خیلی وقتها توی کتابخونهها و لایههای غیر UI، از async/await استفاده میشه ولی ناخواسته Performance و Scale خراب میشه؛ فقط به خاطر برنگشتنِ درست به Thread قدیمی.
نکتهٔ مهم اینه: در کدهای غیر UI (مثل لایهٔ Data Access، Service، Library) معمولاً نیازی نیست بعد از
✅ ایده:
هرجا در Library Code هستیم و بعد از await به Context قبلی نیاز نداریم، از
- Deadlockهای کلاسیک در ASP.NET قدیمی کمتر بشه
- Performance بهتر بشه چون نیاز به Capture/Restore Context نیست
مثال ساده در یک Service غیر UI:
📌 نکات مهم:
- توی UI (WPF, WinForms, MAUI) یا Razor Pages که بعد از await میخوای کنترلهای UI رو آپدیت کنی، از ConfigureAwait(false) استفاده نکن چون به Thread UI برنمیگردی.
- در ASP.NET Core بهخاطر نداشتن SynchronizationContext کلاسیک، مشکل Deadlock خیلی کمتره؛ ولی هنوز هم برای Libraryهای عمومی، استفاده از
- سعی کن این الگو رو توی کل لایههای Library یکدست نگه داری تا رفتار کد قابلپیشبینی بمونه.
برای توضیح رسمی مایکروسافت دربارهٔ async/await و Context:
مستندات async در C# (Microsoft Docs)
امتحان این روش توی Serviceها و Libraryها، مخصوصاً زیر لود بالا، خیلی زود توی لاگها و Performance خودش رو نشون میده 🚀
🔖 #CSharp #سی_شارپ #CSharp #async #ConfigureAwait #Performance #_NET
👤 Developix
💎 Channel: @DevelopixCSharp
خیلی وقتها توی کتابخونهها و لایههای غیر UI، از async/await استفاده میشه ولی ناخواسته Performance و Scale خراب میشه؛ فقط به خاطر برنگشتنِ درست به Thread قدیمی.
نکتهٔ مهم اینه: در کدهای غیر UI (مثل لایهٔ Data Access، Service، Library) معمولاً نیازی نیست بعد از
await برگردیم به همون SynchronizationContext قبلی. اینجاست که 🧠 ConfigureAwait(false) کمک میکنه.✅ ایده:
هرجا در Library Code هستیم و بعد از await به Context قبلی نیاز نداریم، از
ConfigureAwait(false) استفاده کنیم تا:- Deadlockهای کلاسیک در ASP.NET قدیمی کمتر بشه
- Performance بهتر بشه چون نیاز به Capture/Restore Context نیست
مثال ساده در یک Service غیر UI:
public async Task<UserDto> GetUserAsync(int id)
{
// فرض: این متد توی لایه Service یا Repository صدا زده میشه
using var client = new HttpClient();
var response = await client
.GetAsync($"https://api.example.com/users/{id}")
.ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var json = await response.Content
.ReadAsStringAsync()
.ConfigureAwait(false);
return JsonSerializer.Deserialize<UserDto>(json)!;
}
📌 نکات مهم:
- توی UI (WPF, WinForms, MAUI) یا Razor Pages که بعد از await میخوای کنترلهای UI رو آپدیت کنی، از ConfigureAwait(false) استفاده نکن چون به Thread UI برنمیگردی.
- در ASP.NET Core بهخاطر نداشتن SynchronizationContext کلاسیک، مشکل Deadlock خیلی کمتره؛ ولی هنوز هم برای Libraryهای عمومی، استفاده از
ConfigureAwait(false) یک Practice خوب حساب میشه.- سعی کن این الگو رو توی کل لایههای Library یکدست نگه داری تا رفتار کد قابلپیشبینی بمونه.
برای توضیح رسمی مایکروسافت دربارهٔ async/await و Context:
مستندات async در C# (Microsoft Docs)
امتحان این روش توی Serviceها و Libraryها، مخصوصاً زیر لود بالا، خیلی زود توی لاگها و Performance خودش رو نشون میده 🚀
🔖 #CSharp #سی_شارپ #CSharp #async #ConfigureAwait #Performance #_NET
👤 Developix
💎 Channel: @DevelopixCSharp
🔥3
این کد C# را در نظر بگیرید:
در این پیادهسازی از static HttpClient استفاده شده، اما همچنان یک Memory Leak / Thread-Safety Anti Pattern جدی در نحوه تنظیم
چه چیزی باید در این کلاس اصلاح شود تا استفاده از HttpClient هم ایمنتر و هم بدون این Anti Pattern باشد؟
🔖 #CSharp #سی_شارپ
👤 Developix
💎 Channel: @DevelopixCSharp
public class UserService
{
private static HttpClient _client = new HttpClient();
public async Task<string> GetUserNameAsync(int id)
{
_client.BaseAddress = new Uri("https://api.example.com/");
_client.DefaultRequestHeaders.Clear();
_client.DefaultRequestHeaders.Add("X-Request-Id", Guid.NewGuid().ToString());
var response = await _client.GetAsync($"users/{id}");
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
}
در این پیادهسازی از static HttpClient استفاده شده، اما همچنان یک Memory Leak / Thread-Safety Anti Pattern جدی در نحوه تنظیم
BaseAddress و DefaultRequestHeaders وجود دارد که در سناریوهای چند-ترد یا چند-ریکوئست میتواند مشکلساز شود.چه چیزی باید در این کلاس اصلاح شود تا استفاده از HttpClient هم ایمنتر و هم بدون این Anti Pattern باشد؟
🔖 #CSharp #سی_شارپ
👤 Developix
💎 Channel: @DevelopixCSharp
👍3❤1
خیلی از Memory Leakهای ریز تو پروژههای #CSharp از یه چیز ساده شروع میشن: فراموشکردن Dispose روی resourceهایی مثل
تو داتنت جدید، using راحتتر و خواناتر شده و اگر درست استفاده بشه، هم کد تمیزتر میشه هم از نشت حافظه و handleها جلوگیری میکنه. 👇
۱️⃣ الگوی قدیمی using بلاکی
اینجا بهمحض خروج از بلاک، هر دو object بهصورت خودکار Dispose میشن.
۲️⃣ الگوی جدید using declaration (از C# 8 به بعد)
برای کاهش nesting و خوانایی بیشتر:
تو این حالت، scopeِ
۳️⃣ نکته مهم در متدهای طولانی
اگر متد خیلی طولانیه و resource فقط تو یه بخش کوچیک لازم میشه، بهتره همون الگوی بلاکی رو نگه داری تا resource زودتر آزاد بشه و تا آخر متد تو حافظه نمونه.
۴️⃣ async و IAsyncDisposable
برای کلاسهایی که
اینجا در انتهای scope، بهجای
جمعبندی: استفاده درست از using (بهخصوص
🔗 مرجع رسمی Microsoft Docs:
https://learn.microsoft.com/dotnet/csharp/language-reference/statements/using
🔖 #CSharp #سی_شارپ #C# #using #dispose #memory #performance #_NET
👤 Developix
💎 Channel: @DevelopixCSharp
HttpClient، SqlConnection، فایلها و… 😅تو داتنت جدید، using راحتتر و خواناتر شده و اگر درست استفاده بشه، هم کد تمیزتر میشه هم از نشت حافظه و handleها جلوگیری میکنه. 👇
۱️⃣ الگوی قدیمی using بلاکی
using (var stream = File.OpenRead("data.json"))
using (var reader = new StreamReader(stream))
{
var content = reader.ReadToEnd();
Console.WriteLine(content);
}
اینجا بهمحض خروج از بلاک، هر دو object بهصورت خودکار Dispose میشن.
۲️⃣ الگوی جدید using declaration (از C# 8 به بعد)
برای کاهش nesting و خوانایی بیشتر:
using var stream = File.OpenRead("data.json");
using var reader = new StreamReader(stream);
var content = reader.ReadToEnd();
Console.WriteLine(content);
// در انتهای متد، خودشون Dispose میشن
تو این حالت، scopeِ
using var کل متده؛ یعنی پایان متد = زمان Dispose. این الگو توی متدهای کوتاه و تمیز عالی جواب میده و از بلاکهای تو در تو کم میکنه. 💡۳️⃣ نکته مهم در متدهای طولانی
اگر متد خیلی طولانیه و resource فقط تو یه بخش کوچیک لازم میشه، بهتره همون الگوی بلاکی رو نگه داری تا resource زودتر آزاد بشه و تا آخر متد تو حافظه نمونه.
۴️⃣ async و IAsyncDisposable
برای کلاسهایی که
IAsyncDisposable رو پیادهسازی میکنن (مثلاً بعضی clientهای شبکه):await using var client = new SomeAsyncClient();
await client.DoWorkAsync();
اینجا در انتهای scope، بهجای
Dispose، متد DisposeAsync صدا زده میشه و resourceها بهشکل async آزاد میشن.جمعبندی: استفاده درست از using (بهخصوص
using var و await using) یه راه خیلی ساده و کاربردی برای جلوگیری از Memory Leak و تمیز نگهداشتن کده. چند جای پروژه رو که resource سنگین دارن چک و این الگو رو اعمال کن؛ تأثیرش تو performance و پایداری سرویس کاملاً قابل لمسه. 🚀🔗 مرجع رسمی Microsoft Docs:
https://learn.microsoft.com/dotnet/csharp/language-reference/statements/using
🔖 #CSharp #سی_شارپ #C# #using #dispose #memory #performance #_NET
👤 Developix
💎 Channel: @DevelopixCSharp
❤1
❓ در نمونه کد بالا در نسخهٔ اول برای محاسبهٔ میانگین یک کالکشن از اعداد، تمام دادهها دو بار پیمایش و چندین بار boxing/unboxing انجام میشود که هم روی کارایی و هم روی مصرف مموری در سناریوهای پردازش حجم بالای داده تأثیر منفی دارد. با استفاده از Generic و Delegate مناسب (مثل
🔖 #CSharp #سی_شارپ
👤 Developix
💎 Channel: @DevelopixCSharp
Func<T, double>) میتوان منطق را طوری پیادهسازی کرد که هم type-safe باشد و هم فقط یک بار روی دادهها پیمایش شود. کدام نسخه از این پیادهسازی در سناریوهای real-world (مثلاً پردازش لاگ، دادههای سنسور یا تراکنشها) مناسبتر است و چرا استفاده از object و is چکهای پیاپی میتواند به یک Anti Pattern در طراحی APIهای عمومی تبدیل شود؟🔖 #CSharp #سی_شارپ
👤 Developix
💎 Channel: @DevelopixCSharp
👎1
🕒 NodaTime؛ خداحافظ DateTime گیجکننده
کار با
اینجا NodaTime وارد میشه؛ یک کتابخانه قدرتمند برای مدیریت زمان و تاریخ که مدلش خیلی شفافتر از
چرا NodaTime؟
• تایپهای واضح مثل
• پشتیبانی دقیق از IANA Time Zone
• جلوگیری از باگهای زمانبندی، مخصوصاً اطراف تغییر ساعت (DST)
• API تمیز و قابل تست؛ مخصوصاً برای Domain-Driven Design
نصب با NuGet:
نمونه استفاده ساده:
برای هر سرویسی که زمان و زمانبندی توش مهمه، همراه کردنش با NodaTime جلوی کلی Memory Bug و رفتار عجیب رو میگیره. پیشنهاد میشه حتماً تو پروژه بعدی امتحان بشه و کمکم
مستندات رسمی:
Website & Docs
GitHub
🔖 #CSharp #سی_شارپ #CSharp #NodaTime #_NET #Time #DateTime #Backend
👤 Developix
💎 Channel: @DevelopixCSharp
کار با
DateTime و TimeZone در .NET مخصوصاً در پروژههای چندمنطقهای واقعاً دردسرسازه؛ از UTC و Local گرفته تا DST و Offsetهای مختلف. اینجا NodaTime وارد میشه؛ یک کتابخانه قدرتمند برای مدیریت زمان و تاریخ که مدلش خیلی شفافتر از
DateTime پیشفرضه و توی پروژههای مالی، رزرو، لاگینگ و سرویسهای بینالمللی عالی جواب میده. 🚀چرا NodaTime؟
• تایپهای واضح مثل
Instant، LocalDate، LocalDateTime، ZonedDateTime• پشتیبانی دقیق از IANA Time Zone
• جلوگیری از باگهای زمانبندی، مخصوصاً اطراف تغییر ساعت (DST)
• API تمیز و قابل تست؛ مخصوصاً برای Domain-Driven Design
نصب با NuGet:
dotnet add package NodaTime
نمونه استفاده ساده:
using NodaTime;
var now = SystemClock.Instance.GetCurrentInstant();
var tz = DateTimeZoneProviders.Tzdb["Europe/Berlin"];
var zoned = now.InZone(tz);
LocalDate invoiceDate = new(2026, 1, 26);
LocalDate dueDate = invoiceDate.PlusDays(14);
برای هر سرویسی که زمان و زمانبندی توش مهمه، همراه کردنش با NodaTime جلوی کلی Memory Bug و رفتار عجیب رو میگیره. پیشنهاد میشه حتماً تو پروژه بعدی امتحان بشه و کمکم
DateTime خام رو کنار بذاری. 💡مستندات رسمی:
Website & Docs
GitHub
🔖 #CSharp #سی_شارپ #CSharp #NodaTime #_NET #Time #DateTime #Backend
👤 Developix
💎 Channel: @DevelopixCSharp
👍4
در کد زیر تلاش شده یک Singleton ساده پیادهسازی شود، اما هم از نظر Thread-Safety و هم از نظر الگوی طراحی، چند مشکل جدی دارد و در سناریوهای Multi-Thread ممکن است چند نمونه از کلاس ساخته شود.
چه چیزی باید در این پیادهسازی اصلاح شود تا الگوی Singleton بهصورت ایمن و صحیح در سیشارپ پیادهسازی شود؟
🔖 #CSharp #سی_شارپ
👤 Developix
💎 Channel: @DevelopixCSharp
چه چیزی باید در این پیادهسازی اصلاح شود تا الگوی Singleton بهصورت ایمن و صحیح در سیشارپ پیادهسازی شود؟
🔖 #CSharp #سی_شارپ
👤 Developix
💎 Channel: @DevelopixCSharp
در نمونهکد بالا در نسخهی اشتباه، بهجای استفاده از LINQ و عملگرهای آماده برای حذف عناصر تکراری، بهصورت دستی روی لیست حلقه زده شده و برای هر آیتم یک
کدام رویکرد را برای سناریوهای Real-World با حجم داده بالا منطقیتر میدانید و چرا در Collections بزرگ، پرهیز از حلقههای تو در تو (Nested) تا این حد اهمیت دارد؟
🔖 #CSharp #سی_شارپ
👤 Developix
💎 Channel: @DevelopixCSharp
Any() جداگانه روی result صدا زده شده است؛ این کار در سناریوهایی که تعداد رکوردها زیاد است، باعث پیچیدگی زمانی O(n²)، افزایش فشار روی GC و کاهش کارایی میشود. در نسخهی اصلاحشده با استفاده از GroupBy و انتخاب آخرین آیتم هر گروه (براساس Timestamp)، هم کد خواناتر شده و هم فقط یک بار روی مجموعه اصلی پیمایش انجام میشود که در سناریوهای پردازش لاگ یا Events حجیم، مصرف CPU را بهطور محسوسی کاهش میدهد.کدام رویکرد را برای سناریوهای Real-World با حجم داده بالا منطقیتر میدانید و چرا در Collections بزرگ، پرهیز از حلقههای تو در تو (Nested) تا این حد اهمیت دارد؟
🔖 #CSharp #سی_شارپ
👤 Developix
💎 Channel: @DevelopixCSharp
❤1👍1
Forwarded from ابر ویراک
ویراک کلود | تجربهی ابری بدون محدودیت ☁️🚀
🎁 ۲۰٪ شارژ هدیه روی اولین واریزی
مزیتهایی که واقعاً فرق میسازن:
⚡️ پهنای باند 980 مگ
🌐با IP مازاد
⏱️ راهاندازی فوری
💳 پرداخت ساعتی
🛡 پشتیبانی ۲۴/۷
💬 هر سوالی داشتی، تیم ما کنارتـه
✅ مناسب استارتاپها، تیمهای فنی، تا سازمانهای بزرگ
همین الان شروع کن و با حداکثر منابع، سریعتر رشد کن 👇🏻
📞 تماس سریع: 02191555530
🔗 https://virakcloud.com
🎁 ۲۰٪ شارژ هدیه روی اولین واریزی
مزیتهایی که واقعاً فرق میسازن:
⚡️ پهنای باند 980 مگ
🌐با IP مازاد
⏱️ راهاندازی فوری
💳 پرداخت ساعتی
🛡 پشتیبانی ۲۴/۷
💬 هر سوالی داشتی، تیم ما کنارتـه
✅ مناسب استارتاپها، تیمهای فنی، تا سازمانهای بزرگ
همین الان شروع کن و با حداکثر منابع، سریعتر رشد کن 👇🏻
📞 تماس سریع: 02191555530
🔗 https://virakcloud.com