<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های امید احمدپور</title>
        <link>https://virgool.io/feed/@ahmadpooromid</link>
        <description>NET Backend Developer / Software Engineer and Consultant.</description>
        <language>fa</language>
        <pubDate>2026-06-10 12:55:22</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/135357/avatar/WoHfLf.png?height=120&amp;width=120</url>
            <title>امید احمدپور</title>
            <link>https://virgool.io/@ahmadpooromid</link>
        </image>

                    <item>
                <title>کجا می توانیم از Task.WhenAll استفاده کنیم و چگونه؟</title>
                <link>https://virgool.io/@ahmadpooromid/%DA%A9%D8%AC%D8%A7-%D9%85%DB%8C-%D8%AA%D9%88%D8%A7%D9%86%DB%8C%D9%85-%D8%A7%D8%B2-taskwhenall-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%DA%A9%D9%86%DB%8C%D9%85-%D9%88-%DA%86%DA%AF%D9%88%D9%86%D9%87-nv7eumbl6pn5</link>
                <description>در برنامه نویسی Asynchronous در سی شارپ، برای نوشتن کدهایی با پرفرمنس بهتر، روش هایی وجود دارد. یکی از این روش ها استفاده از Task.WhenAll است.اما کجا می توانیم از آن استفاده می کنیم؟در این مقاله به این موضوع می پردازیم و شرایطی را بررسی می کنیم که استفاده از Task.WhenAll این امکان را به ما می دهد که کد با پرفرمنس بهتری بنویسیم.C#شرایطی را در نظر بگیرید که ما کارهایی می خواهیم انجام دهیم که این کارها بصورت متوالی و پشت سرهم نیستند.برای مثال در کد پایین ما چندین تسک مستقل داریم که می خواهیم یک فایل لاگ را ایجاد کنیم. این کار را با دو روش انجام می دهیم.در روش اول به شکل زیر در یک حلقه هزارتایی، متد CreateNewLogAsync را فراخوانی می کنیمDoWithoutTaskWhenAllدر روش دوم از Task.WhenAll به شکل زیر استفاده می کنیم:DoWithUseOfTaskWhenAllبا مقایسه دو کد بالا متوجه می شویم که زمان اجرا روش دوم خیلی کمتر از روش اول است و پرفرمنس به مراتب بالاتری دارد.دلیل این امر این است که در روش اول کارها بصورت متوالی و پشت سرهم اجرا می شوند اما در روش دوم با استفاده از Task.WhenAll کارها بصورت موازی(parallel) انجام می گیرند.نتیجه اینکه اگر چندین متد مستقل asynchronous در کد شما وجود دارد به طوری که هرکدام باید منتظر تکمیل متد قبلی باشد، به این نکته توجه کنید که می توانید با استفاده از Task.WhenAll کد بهتری بنویسید.در پایین می توانید کل کدهای این قسمت را ملاحظه کنید و پرفرمنس آنها را باهم مقایسه نمایید. https://gist.github.com/omid-ahmadpour/4791bf5249111e9daef74fcfca6962bb </description>
                <category>امید احمدپور</category>
                <author>امید احمدپور</author>
                <pubDate>Fri, 26 Nov 2021 00:01:55 +0330</pubDate>
            </item>
                    <item>
                <title>دلیل Immutable بودن String در سی شارپ و بررسی رفتار آن</title>
                <link>https://virgool.io/@ahmadpooromid/%D8%AF%D9%84%DB%8C%D9%84-immutable-%D8%A8%D9%88%D8%AF%D9%86-string-%D8%AF%D8%B1-%D8%B3%DB%8C-%D8%B4%D8%A7%D8%B1%D9%BE-%D9%88-%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-%D8%B1%D9%81%D8%AA%D8%A7%D8%B1-%D8%A2%D9%86-raqviabwfawx</link>
                <description>در دنیای برنامه نویسی از String برای نمایش و ذخیره یک متن استفاده می شود.در زبان برنامه نویسی سی شارپ، String ها بصورت یک آرایه از کاراکترها هستند که با هم کنار قرار گرفتن این کاراکترها، متن مورد نظر شکل می گیرد.Immutable Stringهمچنین در سی شارپ string در دسته reference type ها قرار می گیرد و بر روی heap ذخیره می شود.در سی شارپ string بصورت immutable پیاده سازی شده است. Immutable به معنی فقط خواندنی است به عبارت دیگر وقتی شما یک متغیر string تعریف و مقداردهی می کنید، دیگر نمی توانید آنرا تغییر دهید.در سی شارپ، CLR تعیین می کند که string ها کجا ذخیره شوند. موقعی که شما یک متغیر string تعریف می کنید، CLR در پشت صحنه یک آرایه از کاراکترها برای ذخیره مقدار موردنظر تعریف می کند.همانطور که می دانید هنگام تعریف آرایه ها باید طول آرایه مشخص شود و بعد از تعریف آن، طول آرایه قابل اضافه و کم کردن نیست.موقعی که شما مقدار string را تغییر می دهد چون مقدار قبلی که یک آرایه از کاراکترها است و قابل تغییر نیست، بنابراین مقدار جدید را در یک آرایه جدید کپی یا Clone می کند و با این کار یک بلوک جدید از خانه های حافظه را به آن اختصاص داده می دهد.در واقع، هنگامیکه شما مقدار یک string را تغییر می دهید، CLR یک بلوک جدید از خانه های حافظه را به آن اختصاص می دهد.تغییرناپذیر بودن string، مزایا و معایبی دارد که در ذیل به آن می پردازیم.مزایای Immutable بودن String:یکی از مزایای آن thread-safe بودن است. اگر شما در سیستم های multi-threaded کد میزنید، دیگر مشکلات deadlock و همزمانی را نخواهی داشت. بدین معنی که وقتی شما یک string را تغییر می دهید در واقع شما یک آبجکت جدید در حافظه تعریف می کنید.مزیت دیگر این است که دیگر شما نگران تغییر تصادفی مقدار آنها نخواهی بود و نیاز به اقدامات دیگر که هنگام کار با آبجکت های mutable لازم است، نیست.معایب Immutable بودن String:عیب اصلی آن می تواند تغییر های زیاد یک string باشد که موجب اختصاص فضای جدید حافظه می گردد و مشکلات پرفرمنسی به همراه دارد.نمونه ای از این مشکل را می توانید در قطعه کد زیر ببینید.Sample Codeهمانطور که در قطعه کد بالا که یک برنامه Console است ملاحظه می کنید، در حلقه for به ازای هربار اجرا متغیر myVariable مقدار دهی می شود و پرینت انجام می شود.تا زمانیکه string در اینجا Immutable باشد به ازای هربار اجرا، CLR مقداری از حافظه را به متغیر جدید اختصاص می دهد و هربار اجرا مقدار بیشتری از حافظه را برای ذخیره مقدار مورد نظر اختصاص می دهد.* در مقالات بعدی به نکاتی می پردازیم که می تواند هنگام کار با string از این مشکلات جلوگیری شود* CLR : Common Language Runtime</description>
                <category>امید احمدپور</category>
                <author>امید احمدپور</author>
                <pubDate>Sat, 30 Oct 2021 15:01:55 +0330</pubDate>
            </item>
                    <item>
                <title>کاربرد EventBus و معرفی پکیج NeoBus</title>
                <link>https://virgool.io/@ahmadpooromid/%DA%A9%D8%A7%D8%B1%D8%A8%D8%B1%D8%AF-eventbus-%D9%88-%D9%85%D8%B9%D8%B1%D9%81%DB%8C-%D9%BE%DA%A9%DB%8C%D8%AC-neobus-rveoqqgefbmu</link>
                <description>سوال اول اینه که EventBus اصلا چیه؟در جواب میشه گفت که EventBus مکانیزمیه که بهتون این امکان رو میده که کامپوننت های مختلف بتونن باهم ارتباط برقرار کنند بدون اینکه اطلاعی از همدیگه داشته باشند.بدین صورت که یک کامپوننت میتونه یک Event روی EventBus  ارسال کنه بدون اینکه اطلاعی از این داشته باشه که چه کسی این Event رو دریافت میکنه یا اینکه چه تعدادی کامپوننت دیگه این Event رو دریافت می کنن.اینجوری میشه که این کامپوننت ها میتونن باهم در ارتباط باشن بدون اینکه به هم وابستگی داشته باشند و اصطلاحا Depend هم نباشند.EventBusسوالی که ممکنه براتون پیش بیاد اینه که Component  چیه؟کامپوننت(Component) در اینجا میتونه هرچی باشه اما اغلب آبجکت هایی هستند که میتونن Event ارسال یا دریافت کنن.و اینکه Event چیه؟وقایع یا Eventها اتفاقاتی هستند که داخل سیستم اتفاق میفتند و میشه گفت پیام هایی هستند که بین Componentها رد و بدل میشه.مثلا یک مثال تو سیستم فروشگاهی بزنیم، اینکه مثلا تو کامپوننت سفارش یک کالا بعد اینکه هزینه آن پرداخت و خریداری شد، درنتیجه یک محصول از تعداد محصولامون کم میشه و باید این تغییرات در کامپوننت یا سیستم انبارمون هم ثبت بشه. این پروسه میتونه در قالب ارسال یک Event باشه که توسط کامپوننت سفارش ارسال میشه و کامپوننت انبار هم اونو دریافت میکنه و تغییرات مدنظر اتفاق میفته.اینجوری ما تونستیم در عین حال که وابستگی دوتا کامپوننت یا ماژول رو از بین بردیم درعین حال ارتباط اونها و Consistency سیستم رو هم حفظ کنیم.حال تو Net. یک EventBus طراحی کردم که میتونه Command و Query و هم Event های InMemory ارسال کنه.شما همچنین امکان ارسال Eventهای Distributed هم دارین، بدینصورت که اگر شما دوتا اپلیکیشن روی دوتا سرور مختلف هم داشته باشین باز هم میتونین با EventBus ارتباط بینشون رو برقرار کنین و Event ارسال کنین.NeoBusاگه از CQRS استفاده می کنید این پکیج میتونه خیلی کارتون رو راحت کنه و در واقع این EventBus مختص پروژه هایی که در قالب CQRS نوشته شده، طراحی شده اما میتونین تو پروژه ها و سیستم های دیگه هم ازش استفاده کنین.این پکیج NeoBus نام داره و میتونین اونو از NuGet Package دریافت کنین.NeoBus NuGet Packageفقط کافیه که  بعد راه اندازی Kafka و سپس نصب نوگت پکیج NeoBus، طبق دستورالعملی که تو گیت هاب پروژه منتشر شده پیش برین.همچنین یک پروژه تست که از NeoBus استفاده کرده و پیاده سازی های مختف داخلش هست تو گیت هاب پروژه قرار داده شده که خیلی راحت میتونین طرز کار باهاش رو یاد بگیرین.در پایان اگر سوالی داشتید یا اینکه فیچر جدیدی خواستین بهش اضافه بشه تو گیت های پروژه میتونین Issue ثبت کنین.خوشحال میشم اگه چیزی از این پروژه یاد گرفتین یا تو پروژه هاتون ازش استفاده کردین، در گیت هاب پروژه ستاره هم بدین.آدرس گیت هاب پروژه: NeoBus GitHub</description>
                <category>امید احمدپور</category>
                <author>امید احمدپور</author>
                <pubDate>Tue, 01 Jun 2021 00:50:52 +0430</pubDate>
            </item>
                    <item>
                <title>چرا برنامه نویسان باید کتاب بخوانند؟</title>
                <link>https://virgool.io/@ahmadpooromid/%DA%86%D8%B1%D8%A7-%D8%A8%D8%A7%DB%8C%D8%AF-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3-%D9%87%D8%A7-%DA%A9%D8%AA%D8%A7%D8%A8-%D8%A8%D8%AE%D9%88%D9%86%D9%86%D8%AF-x9snhkdyxjik</link>
                <description>Software was invented to be &quot;soft.&quot; It was intended to be a way to easily change the behavior of machines. If we&#x27;d wanted to the behavior of machines to be hard to change, we would have called it hardware.Clean Architecture - A Craftsman&#x27;s Guid to Software Structure and DesignClean Architectureتو همون صفحات اول کتاب Clean Architecture با همچین جمله ای مواجه میشین، کتابی که حاصل تقریبا 50 سال تجربه برنامه نویسی یک مهندس نرم افزار عالی رتبه هست.باید بگم که همین جمله رو اگه بسط بدیم میشه چند کتاب دیگه ازش درآورد.اصلا این جمله یعنی چی؟ چرا یک مهندس رده بالا مثل Robert C Martin یا همون عمو باب خودمون کتابشو با همچین موضوعی شروع کرده؟به عنوان یک برنامه نویس باید بگم که تو چن سال تجربه ای که دارم تا حالا ندیدم که برنامه ای نوشته بشه که بعدش هیچ تغییری نکنه یا اینکه بعدش هیچ نیازمندی بهش اضافه نشه.اساسا نرم افزار نوشته میشه که تغییر کنه، پس بنظرم چه به عنوان برنامه نویس، چه به عنوان  Cto ، چه به عنوان  Stakeholder، چه به عنوان سرمایه گذار سعی بر تولید برنامه ای داشته باشیم که علاوه بر اینکه کار کنه، بعدا قابل توسعه باشه و بشه نیازمندی های جدید رو هم سریع بهش اضافه کرد.چون اگه این اتفاق نیفته، اولین مشکلاتی که پیش میاد اینه که خود برنامه نویس های اون پروژه دیگه از کار کردن روی اون پروژه خسته میشن، چونکه برای ی تغییر کوچک باید کلی کار انجام بدن و سرعت اضافه کردن نیازمندی های جدید خیلی پایین میاد و کارفرما همیشه از پایین بودن سرعت کار گله داره و کدها اینقد کثیفه که دیگه هیچ برنامه نویس دیگه ای هم حاضر نیس رو پروژه شما کار کنه و در نهایت دودش تو چشم خودتون میره.پس همش فقط به فکر کار کردن برنامه به هر قیمتی نباشیم، وظیفه ماست که از لحاظ تکنیکال طراحی درستی انجام بدیم.برای اینکه بتونید طراحی درست انجام بدین باید نسبت به یک سری مسائل درک درستی داشته باشید.از کارهای مهمی که یک برنامه نویس حتما باید انجام بده، اینه که کتاب بخونه، بدون خوندن کتاب نمی تونید نسبت به خیلی از مسائل درک درستی داشته باشید و قطعا مهندس خوبی هم نخواهید شد و در سطح همون کدنویس باقی می مونید.در لینک زیر، لیستی از کتاب هایی که میتونه به یک مهندس نرم افزار تبدیلتون کنه رو قرار دادم. با خوندن این کتاب ها میتونید هزاران پله رشد کنید.Top Programming Books</description>
                <category>امید احمدپور</category>
                <author>امید احمدپور</author>
                <pubDate>Fri, 21 May 2021 19:39:30 +0430</pubDate>
            </item>
                    <item>
                <title>مفهوم و پیاده سازی Scalability در CQRS</title>
                <link>https://virgool.io/@ahmadpooromid/%D9%85%D9%81%D9%87%D9%88%D9%85-%D9%88-%D9%BE%DB%8C%D8%A7%D8%AF%D9%87-%D8%B3%D8%A7%D8%B2%DB%8C-scalability-%D8%AF%D8%B1-cqrs-peixkgrbdgff</link>
                <description>اگر به مبحث CQRS علاقمند هستید و میخواهید بطور کامل و درست اونو تو پروژه های خودتون پیاده سازی کنید و از پرفرمنس اپلیکیشن خود راضی باشید، ریپازیتوری ای که در زیر معرفی می کنم را حتما دنبال کنید.Command Query Responsibility Segregationیکی از مزایای Scalability, CQRS است.بدون Scale کردن ، کل اپلیکیشن ما درون یک سرور قرار دارد و تنها به منابع یک سرور محدود می شود. با گذشت زمان و رشد اپلیکیشن منابع بیشتری مورد نیاز خواهد بود و باید این سرور را قوی تر کنیم که این ماجرا هزینه بر است.چونکه عملیات خواندن بیشتر از نوشتن، آپدیت و حذف اطلاعات درخواست می شود درنتیجه بار بیشتری روی کوری های اپلیکیشن هست ، پس جداسازی دیتابیس های Query و Command می تواند تاثیر چشمگیری در سرعت و کارایی اپلیکیشن شما داشته باشد.بدین ترتیب می توانیم برای عملیات Read، سرور را قویتر و برای باقی عملیات از سرورهای ضعیف تر استفاده کنیم و این چیزی است که توسط Scalability فراهم می شود.در این پروژه کانتکست ها و ریپازیتوری های خواندن و نوشتن جدا شده است و به این ترتیب میتونید در Query ها از کانتکست یا ریپازیتوری خواندن و در Command ها از کانتکست یا ریپازیتوری نوشتن استفاده کنید.یک راه برای جداسازی دیتابیس های خواندن و نوشتن استفاده از تکنیک Always On اسکول سرور است که بعد از پیاده سازی آن، شما می توانید کانکشن استرینگ های دیتابیس های خود را در فایل appsettings.json قرار داده و دیتابیس Command و Query اپلیکیشن خود را بدین ترتیب جدا سازی نمایید.راه حل دیگر می تواند این باشد که در پیاده سازی ریپازیتوری خواندن خود از Dapper ORM  برای کوری گرفتن استفاده کنید که کارایی و سرعت آن در مواردی به مراتب بیشتر از ef است.یک راه بهتر می تواند طراحی دیتابیسی باشد که جداول Denormal و Flat داشته باشد که تمام فیلدهای مورد نیاز درون آن قرارگیرد. سپس با هر بار درج اطلاعات در دیتابیس Command این جداول نیر آپدیت شوند. با داشتن این جداول دیگر نیاز به Join های عجیب و غریب SQL  نداریم.بسته به بیزینس مورد نظر و منابع موجود می توانید از تکنیک ها، ابزارها و دیتابیس های دیگری هم در پیاده سازی های خود استفاده کنید.Clean Architecture and CQRS implementation</description>
                <category>امید احمدپور</category>
                <author>امید احمدپور</author>
                <pubDate>Thu, 13 May 2021 14:22:53 +0430</pubDate>
            </item>
            </channel>
</rss>