📊 Benchmark
برای اثبات اینکه این روش واقعاً کار میکند، یک برنامه کوچک NET 10. با Aspire و PostgreSQL ساختم.
چون همهچیز روی سیستم محلی اجرا میشد، زمانها خیلی پاییناند؛
اما اگر دیتابیس ریموت بود، اعداد بزرگتر میشدند — نسبتِ سرعت (Speedup Ratio) تقریباً همین میمانَد.
🐢 اجرای ترتیبی (Sequential Execution): حدود ۳۶ms
در حالت ترتیبی، دقیقاً یک Waterfall داریم:
هر Query منتظر تمامشدن Query قبلی میمانَد.
یعنی:
Query 1 → تمام شود → Query 2 → تمام شود → Query 3
این ساختار از لحاظ تجربهٔ کاربری، فوقالعاده کند است. ⏳
⚡️ اجرای موازی (Parallel Execution): حدود ۱۳ms
با رویکرد موازیسازی:
تمام Query ها همزمان شروع میشوند و تقریباً همزمان به پایان میرسند.
نتیجه:
۳ برابر سریعتر
(در این مثال: ۳۶ms → ۱۳ms)
این همان جایی است که تاخیرهای شبکه، I/O و latency دیتابیس را بهصورت مؤثری کاهش میدهیم. 🚀
⚖️ ملاحظات، Trade-off ها و نتیجهگیری
استفاده از IDbContextFactory پلی است بین:
معماری EF Core که بر واحد کار (Unit of Work) و Context واحد طراحی شده و نیازهای مدرن که اجرای موازی حقیقی را میطلبد.
این الگو به شما اجازه میدهد از جعبهٔ
"یک درخواست → یک Thread → یک DbContext"
خارج شوید — بدون اینکه Thread-Safety یا Data Integrity قربانی شود. ✔️
اما باید با احتیاط استفاده شود:
⚠️ 1️⃣ احتمال اتمام Connection Pool
وقتی درخواست قبلاً فقط ۱ Connection مصرف میکرد،
در حال حاضر همان درخواست ۳ Connection میگیرد.
اگر ترافیک بالایی داشته باشید و connection pool کوچک باشد:
ممکن است سریعاً Connection Exhaustion رخ دهد.
این یعنی درخواستها در صف میمانند یا Timeout میدهند. ❗️
⚠️ 2️⃣ سربار Context
اگر Query های شما بسیار سریع هستند (lookup ساده بر اساس ID)،
ساختن چندین Task و DbContext جدید
ممکن است حتی کندتر از حالت ترتیبی شود!
این روش مناسب Query های سنگینتر و پنجرههای بزرگ داده است—not simple queries. ⚙️
🧠 نکتهٔ پایانی
وقتی با یک Dashboard کند مواجه شدید،
قبل از اینکه سراغ SQL دستی یا Stored Procedure بروید…
نگاهی به await های خود بیندازید.
اگر پشتسرهم صف شدهاند،
وقت آن است که کمی فکر موازی انجام دهید. ⚡️
🔖هشتگها:
#EFCore #ParallelProgramming
#AsyncAwait #SoftwareEngineering #IDbContextFactory