| کانال توسعه‌دهندگان سی‌شارپ |
1.03K subscribers
19 photos
3 videos
21 links
⭕️ کانال توسعه‌دهندگان سی‌شارپ دولوپیکس

💠 دولوپیکس | جامعه توسعه‌دهندگان ایرانی

💎 @Developix
🚀 Developix.ir

📌 پشتیبانی و تبلیغات:
@DevelopixSupport
Download Telegram
استفاده حرفه‌ای از ConfigureAwait(false) در async/await

خیلی وقت‌ها توی کتابخونه‌ها و لایه‌های غیر 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# را در نظر بگیرید:

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
👍31
خیلی از Memory Leakهای ریز تو پروژه‌های #CSharp از یه چیز ساده شروع می‌شن: فراموش‌کردن Dispose روی resourceهایی مثل 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 مناسب (مثل Func<T, double>) می‌توان منطق را طوری پیاده‌سازی کرد که هم type-safe باشد و هم فقط یک بار روی داده‌ها پیمایش شود. کدام نسخه از این پیاده‌سازی در سناریوهای real-world (مثلاً پردازش لاگ، داده‌های سنسور یا تراکنش‌ها) مناسب‌تر است و چرا استفاده از object و is چک‌های پیاپی می‌تواند به یک Anti Pattern در طراحی APIهای عمومی تبدیل شود؟

🔖 #CSharp #سی_شارپ

👤 Developix

💎 Channel: @DevelopixCSharp
👎1
🕒 NodaTime؛ خداحافظ DateTime گیج‌کننده

کار با 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
در نمونه‌کد بالا در نسخه‌ی اشتباه، به‌جای استفاده از LINQ و عملگرهای آماده برای حذف عناصر تکراری، به‌صورت دستی روی لیست حلقه زده شده و برای هر آیتم یک 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