<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Farhad Nosrati فرهاد نصرتی</title>
        <link>https://virgool.io/feed/@farhadnosrati</link>
        <description>https://github.com/nosratifarhad</description>
        <language>fa</language>
        <pubDate>2026-07-06 11:45:47</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/788498/avatar/czjeNp.jpeg?height=120&amp;width=120</url>
            <title>Farhad Nosrati فرهاد نصرتی</title>
            <link>https://virgool.io/@farhadnosrati</link>
        </image>

                    <item>
                <title>Understanding Latency Percentiles (P50, P95, and P99)</title>
                <link>https://virgool.io/@farhadnosrati/understanding-latency-percentiles-p50-p95-and-p99-rqdmcpzlezed</link>
                <description>Understanding Latency Percentiles (P50, P95, and P99)IntroductionLatency is one of the most important metrics for measuring the performance of an application or service. It represents the amount of time it takes for a request to be processed—from the moment a client sends the request until it receives the response.When monitoring applications, engineers rarely rely only on the average latency because averages can hide slow requests. Instead, modern monitoring systems report latency percentiles, such as P50, P95, and P99, which provide a much more accurate picture of the user experience.This document explains what latency percentiles are, how they are calculated, and why they are essential for monitoring production systems.What Is a Percentile?A percentile tells us the value below which a certain percentage of observations fall.For latency measurements:P50 means 50% of requests completed in that amount of time or less.P95 means 95% of requests completed in that amount of time or less.P99 means 99% of requests completed in that amount of time or less.To calculate percentiles, all request durations are first sorted from the fastest to the slowest.For example, suppose an API processes 10,000 requests in one hour. After sorting the response times, monitoring tools determine the latency values corresponding to the 50th, 95th, and 99th percentiles.Understanding P50 (Median Latency)The 50th percentile (P50) is also known as the median.If:P50 = 35 msthen:50% of requests completed in 35 ms or lessThe remaining 50% took longer than 35 msP50 represents the typical user experience, since half of all users receive responses faster than this value.Understanding P95The 95th percentile (P95) measures the experience of almost all users.Imagine your application processes 100 requests.After sorting the response times:RequestResponse Time110 ms212 ms......90120 ms91130 ms92140 ms93150 ms94160 ms95180 ms96220 ms97260 ms98350 ms99750 ms1002000 msThe 95th percentile is 180 ms.This means:95 out of 100 requests completed in 180 ms or lessOnly the slowest 5 requests took longer than 180 msNotice that the requests taking 220 ms, 260 ms, 350 ms, 750 ms, and 2000 ms are not included in the P95 value because they belong to the slowest 5%.Larger ExampleSuppose your service processes 10,000 requests.If:P95 = 180 msthen:9,500 requests completed in 180 ms or less500 requests took longer than 180 msThis does not mean every request took 180 ms.It simply means that 95% of all requests completed within 180 milliseconds.Understanding P99The 99th percentile (P99) focuses on the slowest requests and helps identify rare performance problems.Consider the same 100 requests:RequestResponse Time110 ms212 ms......95180 ms96220 ms97260 ms98350 ms99750 ms1002000 msThe 99th percentile is 750 ms.This means:99 out of 100 requests completed in 750 ms or lessOnly 1 request took longer than 750 msNotice that the slowest request (2000 ms) is not the P99 value. It belongs to the remaining 1% of requests that exceeded the 99th percentile.Larger ExampleSuppose your application processes 10,000 requests.If:P99 = 600 msthen:9,900 requests completed in 600 ms or less100 requests took longer than 600 msAgain, this does not mean every request took 600 ms.It simply means that 99% of requests finished within 600 milliseconds.Visual ExampleImagine the sorted response times below:10
12
14
15
16
18
20
...
30
35
40
60
80
120
180
250
400
750
900
1200
A monitoring system might report:MetricValueMinimum10 msAverage42 msP5035 msP95180 msP99750 msMaximum1200 msThis tells us:Most users receive responses within 35 ms.Nearly every user receives a response within 180 ms.Almost all users receive a response within 750 ms.Only a very small number of requests exceed 750 ms.The slowest request took 1200 ms.Why Average Latency Is Not EnoughAverage latency can be misleading because a small number of very slow requests may have little impact on the average.Consider two services.Service A99 requests = 20 ms1 request = 2000 msAverage latency:39.8 ms
Although the average looks good, one user experienced a delay of 2 seconds.Service B100 requests = 40 msAverage latency:40 ms
The average is almost identical to Service A, yet every user receives a consistent experience.This demonstrates why engineers rely on percentiles instead of averages.Why P95 and P99 MatterBoth P95 and P99 provide insights that average latency cannot.P95P95 represents the experience of almost all users.It is commonly used for:Measuring API performanceMonitoring web applicationsDefining Service Level Objectives (SLOs)Tracking customer experienceBecause P95 ignores only the slowest 5% of requests, it provides a stable measurement of overall performance while filtering out extreme outliers.P99P99 focuses on the slowest users and is often called tail latency.It is especially useful for detecting intermittent performance issues such as:Database locksNetwork latency spikesGarbage collection pausesThread starvationHigh CPU utilizationResource contentionInfrastructure problemsP99 is much more sensitive to performance spikes than P95.Even if only 1% of users are affected, those requests often reveal problems that deserve investigation.Real Monitoring ExampleSuppose your monitoring dashboard reports:MetricValueAverage55 msP95140 msP99820 msMaximum4200 msInterpretationMost requests complete quickly (around 55 ms on average).95% of users receive responses within 140 ms.99% of users receive responses within 820 ms.About 1% of requests experience noticeable delays.The slowest request took 4.2 seconds, indicating an occasional performance problem that should be investigated.Choosing the Right MetricEach latency metric answers a different question.MetricMeaningWhat It Tells YouMinimumFastest requestBest-case latencyAverageMean response timeOverall performance, but can hide slow requestsP50Median latencyTypical user experienceP9595% of requests are faster than this valueExperience of almost all usersP9999% of requests are faster than this valuePerformance of the slowest requests (tail latency)MaximumSlowest requestWorst-case latencyBest PracticesWhen monitoring production systems:Never rely solely on average latency.Monitor P50 to understand the typical user experience.Monitor P95 to ensure that almost all users receive acceptable performance.Monitor P99 to detect rare but significant performance issues.Investigate increases in P99 even if the average latency remains unchanged, as this often indicates intermittent bottlenecks.Key TakeawaysLatency measures how long it takes to process a request.Percentiles provide a much better representation of user experience than averages.P50 represents the typical request.P95 represents the experience of almost all users.P99 highlights rare but slow requests and is essential for identifying tail latency.Average latency can hide serious performance problems, whereas P95 and P99 reveal them.Successful production monitoring relies on tracking percentile metrics alongside averages to gain a complete understanding of application performance.</description>
                <category>Farhad Nosrati فرهاد نصرتی</category>
                <author>Farhad Nosrati فرهاد نصرتی</author>
                <pubDate>Mon, 29 Jun 2026 23:58:07 +0330</pubDate>
            </item>
                    <item>
                <title>Task-based asynchronous programming</title>
                <link>https://virgool.io/@farhadnosrati/task-based-asynchronous-programming-n0523nfgjaql</link>
                <description> کتابخانه موازی وظیفه (Task Parallel Library یا TPL) بر پایه مفهومی به نام &quot;وظیفه&quot; (Task) طراحی شده است که نشان‌دهنده یک عملیات غیرهمزمان است. از برخی جنبه‌ها، یک وظیفه شبیه به یک نخ (Thread) یا یک آیتم کاری در ThreadPool است، اما در سطحی بالاتر از انتزاع عمل می‌کند. اصطلاح &quot;موازی‌سازی وظیفه&quot; (Task Parallelism) به اجرای همزمان یک یا چند وظیفه مستقل اشاره دارد. وظایف (Tasks) دو مزیت اصلی ارائه می‌دهند:1. استفاده کارآمدتر و مقیاس‌پذیرتر از منابع سیستمدر پشت صحنه، وظایف به صف ThreadPool ارسال می‌شوند که این صف به وسیله الگوریتم‌هایی بهینه‌سازی شده است که تعداد نخ‌ها را تعیین و تنظیم می‌کنند. این الگوریتم‌ها تعادل بار (Load Balancing) را مدیریت می‌کنند تا بیشترین کارایی حاصل شود. این فرآیند وظایف را سبک و کم‌هزینه می‌کند و این امکان را می‌دهد که تعداد زیادی از آن‌ها ایجاد کنید تا موازی‌سازی جزئی‌تر و دقیق‌تری داشته باشید.2. کنترل بیشتر بر فرآیند نسبت به نخ‌ها یا آیتم‌های کاریوظایف و چارچوبی که حول آن‌ها ساخته شده است، مجموعه گسترده‌ای از APIها را ارائه می‌دهد که شامل قابلیت‌هایی مانند انتظار (Waiting)، لغو (Cancellation)، ادامه (Continuations)، مدیریت استثنائات قوی، گزارش وضعیت دقیق، زمان‌بندی سفارشی و بسیاری ویژگی‌های دیگر است.به همین دلایل، TPL بهترین گزینه برای نوشتن کدهای چندنخی، غیرهمزمان، و موازی در دات‌نت (.NET) است.ایجاد و اجرای وظایف به صورت غیرمستقیمروش Parallel.Invoke یک راه ساده برای اجرای همزمان چندین دستور مختلف ارائه می‌دهد. شما کافی است یک Action برای هر عملیات کاری ارائه دهید. ساده‌ترین روش برای تعریف این Actionها استفاده از عبارت‌های لامبدا (Lambda Expressions) است. این عبارت‌های لامبدا می‌توانند یک متد نام‌گذاری‌شده را فراخوانی کنند یا کد موردنظر را به صورت مستقیم ارائه دهند.در مثال زیر، یک فراخوانی ابتدایی به Parallel.Invoke نشان داده شده است که دو وظیفه ایجاد و اجرا می‌کند که به صورت همزمان اجرا می‌شوند. وظیفه اول یک عبارت لامبدا است که متدی به نام DoSomeWork را فراخوانی می‌کند و وظیفه دوم نیز متدی به نام DoSomeOtherWork را فراخوانی می‌کند:Parallel.Invoke(() =&gt; DoSomeWork(), () =&gt; DoSomeOtherWork());نکته : این مستندات از عبارات لامبدا (Lambda Expressions) برای تعریف نماینده‌ها (Delegates) در TPL استفاده می‌کند. اگر با عبارات لامبدا در C# یا Visual Basic آشنایی ندارید، پیشنهاد می‌کنم به مستندات Lambda Expressions in PLINQ and TPL مراجعه کنید.نکته : تعداد نمونه‌های وظیفه (Task Instances) که در پس‌زمینه توسط متد Invoke ایجاد می‌شوند، لزوماً برابر با تعداد نماینده‌هایی نیست که ارائه داده‌اید. TPL ممکن است بهینه‌سازی‌های مختلفی انجام دهد، به خصوص زمانی که تعداد نماینده‌ها زیاد باشد.یک وظیفه که مقدار بازگشتی ندارد، با کلاس System.Threading.Tasks.Task نمایش داده می‌شود. وظیفه‌ای که یک مقدار بازگشتی دارد، با کلاس System.Threading.Tasks.Task&lt;TResult&gt; نمایش داده می‌شود که از کلاس Task به ارث می‌برد. شیء وظیفه (Task Object) مدیریت جزئیات زیرساخت را انجام می‌دهد و متدها و خواصی را ارائه می‌دهد که در طول عمر وظیفه از نخ فراخوانی قابل دسترسی هستند. به عنوان مثال، شما می‌توانید در هر زمانی به ویژگی Status یک وظیفه دسترسی داشته باشید تا مشخص کنید که آیا وظیفه شروع به اجرا کرده، به پایان رسیده، لغو شده یا استثنایی (Exception) رخ داده است. وضعیت وظیفه با یک شمارش به نام TaskStatus نمایش داده می‌شود.هنگامی که یک وظیفه ایجاد می‌کنید، باید یک نماینده (Delegate) به آن بدهید که کدی را که وظیفه اجرا خواهد کرد، در بر می‌گیرد. این نماینده می‌تواند به صورت یک نماینده نام‌گذاری‌شده، یک متد ناشناس یا یک عبارت لامبدا (Lambda Expression) تعریف شود. عبارات لامبدا می‌توانند شامل فراخوانی به یک متد نام‌گذاری‌شده باشند، همان‌طور که در مثال زیر نشان داده شده است. این مثال شامل فراخوانی متد Task.Wait است تا اطمینان حاصل شود که وظیفه قبل از پایان برنامه در حالت کنسول اجرا را کامل می‌کند.Task taskA = new Task( () =&gt; Console.WriteLine(&amp;quotHello from taskA.&amp;quot));       taskA.Start();taskA.Wait();شما می‌توانید از متدهای Task.Run برای ایجاد و شروع یک وظیفه به صورت همزمان استفاده کنید. متدهای Run همیشه از زمان‌بند پیش‌فرض وظایف استفاده می‌کنند، حتی اگر نخ فعلی از زمان‌بند دیگری استفاده کند.متدهای Run گزینه مناسبی هستند زمانی که نیازی به کنترل بیشتر روی ایجاد و زمان‌بندی وظایف ندارید.Task taskA = Task.Run( () =&gt; Console.WriteLine(&amp;quotHello from taskA.&amp;quot));taskA.Wait();شما همچنین می‌توانید از متد TaskFactory.StartNew برای ایجاد و شروع یک وظیفه به صورت همزمان استفاده کنید. همانطور که در مثال زیر نشان داده شده است، می‌توانید از این متد زمانی استفاده کنید که:ایجاد و زمان‌بندی نیازی به تفکیک نداشته باشند و شما به گزینه‌های اضافی برای ایجاد وظیفه یا استفاده از یک زمان‌بند خاص نیاز داشته باشید.نیاز دارید که وضعیت اضافی را به وظیفه ارسال کنید که بتوانید از طریق ویژگی Task.AsyncState آن را بازیابی کنید.Task&lt;Double&gt;.Factory.StartNew(() =&gt; DoComputation(1000.0));برای اطلاعات بیشتر، به مستندات زیر مراجعه کنید. https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-return-a-value-from-a-task زمانی که از یک عبارت لامبدا برای ایجاد یک نماینده استفاده می‌کنید، به تمامی متغیرهایی که در آن نقطه از کد شما قابل مشاهده هستند دسترسی دارید. با این حال، در برخی موارد، به‌ویژه در داخل حلقه‌ها، لامبدا متغیر را به‌طور مورد انتظار ذخیره نمی‌کند. لامبدا فقط مرجع (Reference) متغیر را ذخیره می‌کند، نه مقدار آن، چون این متغیر بعد از هر بار تکرار تغییر می‌کند. شما می‌توانید با فراهم کردن یک شیء وضعیت (state object) به یک وظیفه از طریق سازنده آن، به مقدار در هر تکرار دسترسی پیدا کنید. این وضعیت به‌عنوان یک آرگومان به نماینده وظیفه (task delegate) ارسال می‌شود و می‌توان از طریق ویژگی Task.AsyncState آن را از شیء وظیفه دسترسی کرد.Task IDهر وظیفه یک شناسه عددی دریافت می‌کند که آن را به‌طور منحصر به فرد در دامنه برنامه شناسایی می‌کند و می‌توان از طریق ویژگی Task.Id به آن دسترسی پیدا کرد. این شناسه برای مشاهده اطلاعات وظایف در پنجره‌های Parallel Stacks و Tasks در دیباگر ویژوال استودیو مفید است. شناسه به‌طور تنبل (lazy) ایجاد می‌شود، به این معنی که تا زمانی که درخواست نشود، ایجاد نمی‌شود. بنابراین، ممکن است هر بار که برنامه اجرا می‌شود، شناسه متفاوتی به وظیفه اختصاص یابد. برای اطلاعات بیشتر در مورد نحوه مشاهده شناسه‌های وظیفه در دیباگر، به مستندات زیر  مراجعه کنید. https://learn.microsoft.com/en-us/visualstudio/debugger/using-the-parallel-stacks-window?view=vs-2022  https://learn.microsoft.com/en-us/visualstudio/debugger/using-the-tasks-window?view=vs-2022 Task creation optionsبیشتر APIهایی که وظایف ایجاد می‌کنند، اضافه‌بارهایی دارند که یک پارامتر از نوع TaskCreationOptions را قبول می‌کنند. با مشخص کردن یک یا چند گزینه از این موارد، شما به زمان‌بند وظیفه می‌گویید که چگونه وظیفه را روی استخر نخ زمان‌بندی کند. این گزینه‌ها ممکن است با استفاده از عملگر OR بیتی ترکیب شوند.مثال زیر یک وظیفه را نشان می‌دهد که گزینه‌های LongRunning و PreferFairness را دارد.var task3 = new Task(() =&gt; MyLongRunningMethod(),                     TaskCreationOptions.LongRunning | TaskCreationOptions.PreferFairness); task3.Start();Tasks, threads, and cultureهر نخ یک فرهنگ و فرهنگ UI مرتبط دارد که به ترتیب توسط ویژگی‌های Thread.CurrentCulture و Thread.CurrentUICulture تعریف می‌شود. فرهنگ یک نخ در عملیاتی مانند قالب‌بندی، تجزیه و تحلیل، مرتب‌سازی و مقایسه رشته‌ها استفاده می‌شود. فرهنگ UI یک نخ در جستجوی منابع استفاده می‌شود.فرهنگ سیستم فرهنگ پیش‌فرض و فرهنگ UI پیش‌فرض نخ را تعریف می‌کند. با این حال، می‌توانید یک فرهنگ پیش‌فرض برای تمام نخ‌ها در یک دامنه برنامه از طریق ویژگی‌های CultureInfo.DefaultThreadCurrentCulture و CultureInfo.DefaultThreadCurrentUICulture مشخص کنید. اگر فرهنگ یک نخ را به‌طور صریح تنظیم کنید و یک نخ جدید راه‌اندازی کنید، نخ جدید فرهنگ نخ فراخوانی را به ارث نمی‌برد؛ در عوض، فرهنگ آن فرهنگ پیش‌فرض سیستم است. با این حال، در برنامه‌نویسی مبتنی بر وظیفه (Task)، وظایف از فرهنگ نخ فراخوانی استفاده می‌کنند، حتی اگر وظیفه به‌صورت غیرهمزمان روی نخ دیگری اجرا شود.مثال زیر یک توضیح ساده ارائه می‌دهد. این مثال فرهنگ فعلی برنامه را به فرانسوی (فرانسه) تغییر می‌دهد. اگر فرانسوی (فرانسه) قبلاً فرهنگ فعلی باشد، به انگلیسی (ایالات متحده) تغییر می‌دهد. سپس یک نماینده به نام formatDelegate فراخوانی می‌شود که برخی از اعداد را به‌عنوان مقادیر ارزی در فرهنگ جدید فرمت می‌کند. چه نماینده به‌طور همزمان یا غیرهمزمان توسط یک وظیفه فراخوانی شود، وظیفه از فرهنگ نخ فراخوانی استفاده می‌کند.نکته : در نسخه‌های پیش از .NET Framework 4.6، فرهنگ یک وظیفه توسط فرهنگ نخی که وظیفه روی آن اجرا می‌شود تعیین می‌شود، نه فرهنگ نخ فراخوانی. برای وظایف غیرهمزمان، فرهنگ استفاده‌شده توسط وظیفه ممکن است با فرهنگ نخ فراخوانی متفاوت باشد.Creating task continuationsمتدهای Task.ContinueWith و Task&lt;TResult&gt;.ContinueWith به شما این امکان را می‌دهند که یک وظیفه را مشخص کنید که پس از اتمام وظیفه قبلی اجرا شود. نماینده وظیفه ادامه‌دهنده یک مرجع به وظیفه قبلی دریافت می‌کند تا بتواند وضعیت آن را بررسی کند. و با بازیابی مقدار ویژگی Task&lt;TResult&gt;.Result، می‌توانید از خروجی وظیفه قبلی به‌عنوان ورودی برای وظیفه ادامه‌دهنده استفاده کنید.چون Task.ContinueWith یک متد نمونه‌ای است، شما می‌توانید فراخوانی‌های متد را به هم متصل کنید، به جای اینکه برای هر وظیفه قبلی یک شیء Task&lt;TResult&gt; ایجاد کنید. Creating detached child tasksزمانی که کدی که در یک وظیفه در حال اجرا است، یک وظیفه جدید ایجاد می‌کند و گزینه AttachedToParent را مشخص نمی‌کند، وظیفه جدید به‌طور خاص با وظیفه والد هماهنگ نمی‌شود. این نوع وظیفه غیرهماهنگ به نام &quot;وظیفه تو در تو جدا شده&quot; یا &quot;وظیفه فرزند جدا شده&quot; شناخته می‌شود.Creating child tasksزمانی که کدی که در یک وظیفه در حال اجرا است، یک وظیفه با گزینه AttachedToParent ایجاد می‌کند، وظیفه جدید به عنوان &quot;وظیفه فرزند متصل&quot; به وظیفه والد شناخته می‌شود. شما می‌توانید از گزینه AttachedToParent برای بیان موازی‌سازی وظایف ساختاریافته استفاده کنید، زیرا وظیفه والد به‌طور ضمنی منتظر اتمام تمام وظایف فرزند متصل می‌ماند. در مثال زیر، یک وظیفه والد ایجاد می‌شود که ۱۰ وظیفه فرزند متصل ایجاد می‌کند. در این مثال، متد Task.Wait برای انتظار برای اتمام وظیفه والد فراخوانی می‌شود و نیازی به انتظار صریح برای اتمام وظایف فرزند متصل نیست.Waiting for tasks to finishانتظار برای اتمام وظایفانواع System.Threading.Tasks.Task و System.Threading.Tasks.Task&lt;TResult&gt; چندین باراضافه از متدهای Task.Wait را فراهم می‌کنند که به شما امکان می‌دهند برای اتمام یک وظیفه صبر کنید. علاوه بر این، باراضافه‌های متدهای ایستا Task.WaitAll و Task.WaitAny به شما این امکان را می‌دهند که برای اتمام هرکدام یا همه وظایف در یک آرایه از وظایف صبر کنید.به‌طور معمول، شما برای یکی از این دلایل برای اتمام یک وظیفه صبر می‌کنید:نخ اصلی به نتیجه نهایی محاسبه‌شده توسط یک وظیفه وابسته است.باید استثناهایی که ممکن است از وظیفه پرتاب شوند را مدیریت کنید.ممکن است برنامه قبل از اتمام تمام وظایف به اتمام برسد. به‌عنوان مثال، برنامه‌های کنسولی پس از اجرای تمام کدهای همگام در متد Main (نقطه ورودی برنامه) خاتمه می‌یابند.مثال زیر الگوی پایه‌ای را نشان می‌دهد که شامل مدیریت استثنا نیست:برای مثالی که مدیریت استثناها را نشان می‌دهد، به &quot;مدیریت استثناها&quot; مراجعه کنید.برخی از باراضافه‌ها به شما این امکان را می‌دهند که یک زمان‌سنج تعیین کنید، و برخی دیگر یک پارامتر اضافی به نام CancellationToken دریافت می‌کنند تا بتوانید خود عمل انتظار را هم به صورت برنامه‌نویسی و هم به پاسخ به ورودی کاربر لغو کنید.وقتی برای یک وظیفه صبر می‌کنید، به‌طور ضمنی برای تمام فرزندان آن وظیفه که با استفاده از گزینه TaskCreationOptions.AttachedToParent ایجاد شده‌اند، صبر می‌کنید. متد Task.Wait بلافاصله اگر وظیفه قبلاً تکمیل شده باشد، بازمی‌گردد. متد Task.Wait هر استثنایی که توسط یک وظیفه پرتاب شده باشد را پرتاب می‌کند، حتی اگر متد Task.Wait پس از اتمام وظیفه فراخوانی شده باشد.Composing tasksکلاس‌های Task و Task&lt;TResult&gt; چندین متد را برای کمک به ترکیب چندین تسک فراهم می‌کنند. این متدها الگوهای رایج را پیاده‌سازی کرده و از ویژگی‌های زبان‌های C#، Visual Basic و F# برای برنامه‌نویسی غیرهمزمان به‌خوبی استفاده می‌کنند. در این بخش متدهای WhenAll، WhenAny، Delay و FromResult توضیح داده شده‌اند.Task.WhenAllمتد Task.WhenAll به‌صورت غیرهمزمان منتظر می‌ماند تا چندین شیء Task یا Task&lt;TResult&gt; تمام شوند. این متد نسخه‌های اضافه‌شده‌ای دارد که به شما این امکان را می‌دهد تا منتظر مجموعه‌های غیر یکنواختی از تسک‌ها باشید. به‌عنوان مثال، می‌توانید منتظر بمانید تا چندین شیء Task و Task&lt;TResult&gt; از یک فراخوانی متد به پایان برسند.Task.WhenAnyمتد Task.WhenAny به‌صورت غیرهمزمان منتظر می‌ماند تا یکی از چندین شیء Task یا Task&lt;TResult&gt; تمام شود. مشابه متد Task.WhenAll، این متد نسخه‌های اضافه‌شده‌ای دارد که به شما این امکان را می‌دهد تا منتظر مجموعه‌های غیر یکنواختی از تسک‌ها باشید. متد WhenAny به‌ویژه در سناریوهای زیر مفید است:عملیات‌های اضافی: فرض کنید الگوریتم یا عملیاتی دارید که می‌تواند به طرق مختلف انجام شود. می‌توانید از متد WhenAny برای انتخاب عملیاتی که زودتر تمام می‌شود استفاده کنید و سپس عملیات‌های باقی‌مانده را لغو کنید.عملیات‌های درهم: می‌توانید چندین عملیات را شروع کنید که باید تمام شوند و از متد WhenAny برای پردازش نتایج هر عملیات به محض اتمام آن استفاده کنید. پس از اتمام یک عملیات، می‌توانید یک یا چند تسک را آغاز کنید.عملیات‌های محدود شده: می‌توانید از متد WhenAny برای گسترش سناریو قبلی با محدود کردن تعداد عملیات‌های همزمان استفاده کنید.عملیات‌های منقضی‌شده: می‌توانید از متد WhenAny برای انتخاب بین یک یا چند تسک و یک تسک که بعد از زمان خاصی تمام می‌شود استفاده کنید، مانند تسکی که از متد Delay برمی‌گردد. متد Delay در بخش بعدی توضیح داده شده است.Task.Delayمتد Task.Delay شیء Task ایجاد می‌کند که پس از مدت زمان مشخصی به پایان می‌رسد. می‌توانید از این متد برای ساخت حلقه‌هایی که داده‌ها را به‌طور دوره‌ای بررسی می‌کنند، تعیین زمان‌گذاری‌ها، به تأخیر انداختن پردازش ورودی کاربر و غیره استفاده کنید.Task&lt;TResult&gt;.FromResultبا استفاده از متد Task.FromResult می‌توانید شیء Task&lt;TResult&gt; ایجاد کنید که یک نتیجه پیش‌محاسبه‌شده را نگه می‌دارد. این متد زمانی مفید است که عملیاتی غیرهمزمان انجام می‌دهید که شیء Task&lt;TResult&gt; باز می‌گرداند و نتیجه آن Task&lt;TResult&gt; قبلاً محاسبه شده باشد. برای مثال، از FromResult می‌توان برای دریافت نتایج عملیات دانلود غیرهمزمان که در کش نگهداری می‌شوند، استفاده کرد.Handling exceptions in tasksهنگامی که یک تسک یک یا چند استثنا پرتاب می‌کند، استثناها در یک استثنای AggregateException بسته می‌شوند. این استثنا به رشته‌ای که با تسک ملحق شده است، منتقل می‌شود. معمولاً این رشته‌ای است که منتظر پایان تسک یا دسترسی به ویژگی Result است. این رفتار سیاست .NET Framework را اعمال می‌کند که طبق آن، تمام استثناهای بدون پردازش به‌طور پیش‌فرض باید فرآیند را خاتمه دهند. کد فراخوانی می‌تواند استثناها را با استفاده از هر یک از موارد زیر در یک بلوک try/catch مدیریت کند:متد Waitمتد WaitAllمتد WaitAnyویژگی Resultرشته ملحق‌شده همچنین می‌تواند استثناها را با دسترسی به ویژگی Exception قبل از جمع‌آوری زباله‌ها مدیریت کند. با دسترسی به این ویژگی، از انتقال استثناهای بدون پردازش که باعث خاتمه فرآیند هنگام نهایی شدن شیء می‌شود، جلوگیری می‌کنید.برای اطلاعات بیشتر در مورد استثناها و تسک‌ها، به مدیریت استثناها مراجعه کنید.Canceling tasksکلاس Task از لغو همکاری پشتیبانی می‌کند و به‌طور کامل با کلاس‌های System.Threading.CancellationTokenSource و System.Threading.CancellationToken که در .NET Framework 4 معرفی شده‌اند، یکپارچه است. بسیاری از سازنده‌های کلاس System.Threading.Tasks.Task یک شیء CancellationToken را به‌عنوان پارامتر ورودی می‌پذیرند. بسیاری از اضافه‌شده‌های متدهای StartNew و Run نیز شامل پارامتر CancellationToken هستند.شما می‌توانید توکن را ایجاد کرده و درخواست لغو را در زمان بعدی با استفاده از کلاس CancellationTokenSource صادر کنید. توکن را به‌عنوان آرگومان به تسک ارسال کرده و همچنین از همان توکن در دلیگیت کاربر خود استفاده کنید که وظیفه پاسخ به درخواست لغو را انجام می‌دهد.برای اطلاعات بیشتر، به لغو تسک‌ها و نحوه لغو یک تسک و فرزندان آن مراجعه کنید.The TaskFactory classکلاس TaskFactory متدهای ایستا را فراهم می‌کند که الگوهای رایج برای ایجاد و شروع تسک‌ها و تسک‌های ادامه‌ای را در بر می‌گیرد.رایج‌ترین الگو، StartNew است که در یک بیانیه، تسک را ایجاد و شروع می‌کند.هنگامی که تسک‌های ادامه‌ای از چندین پیش‌نیاز ایجاد می‌کنید، از متدهای ContinueWhenAll یا ContinueWhenAny یا معادل‌های آنها در کلاس Task&lt;TResult&gt; استفاده کنید. برای اطلاعات بیشتر، به زنجیره‌ای کردن تسک‌ها با استفاده از تسک‌های ادامه‌ای مراجعه کنید.برای گنجاندن متدهای BeginX و EndX مدل برنامه‌نویسی غیرهمزمان در یک شیء Task یا Task&lt;TResult&gt;، از متدهای FromAsync استفاده کنید. برای اطلاعات بیشتر، به TPL و برنامه‌نویسی غیرهمزمان سنتی .NET Framework مراجعه کنید.و TaskFactory پیش‌فرض می‌تواند به‌عنوان یک ویژگی ایستا در کلاس Task یا Task&lt;TResult&gt; دسترسی داشته باشد. همچنین می‌توانید یک TaskFactory را مستقیماً نمونه‌سازی کرده و گزینه‌های مختلفی از جمله یک توکن لغو، گزینه‌های TaskCreationOptions، گزینه‌های TaskContinuationOptions یا یک TaskScheduler را مشخص کنید. هر گزینه‌ای که هنگام ایجاد کارخانه تسک مشخص کنید، به تمام تسک‌هایی که ایجاد می‌کند اعمال می‌شود، مگر اینکه تسک با استفاده از enumeration TaskCreationOptions ایجاد شود، در این صورت گزینه‌های تسک گزینه‌های کارخانه تسک را لغو می‌کنند.Tasks without delegatesدر برخی موارد، ممکن است بخواهید از یک تسک برای دربر گرفتن عملیاتی غیرهمزمان که توسط یک مؤلفه خارجی انجام می‌شود به جای دلیگیت کاربر خود استفاده کنید. اگر عملیات بر اساس الگوی Begin/End مدل برنامه‌نویسی غیرهمزمان باشد، می‌توانید از متدهای FromAsync استفاده کنید. اگر اینطور نباشد، می‌توانید از شیء TaskCompletionSource&lt;TResult&gt; برای پیچیدن عملیات در یک تسک استفاده کنید و به این ترتیب از برخی مزایای برنامه‌نویسی تسک‌ها بهره‌مند شوید. به‌عنوان مثال، پشتیبانی از انتقال استثنا و تسک‌های ادامه‌ای. برای اطلاعات بیشتر، به TaskCompletionSource&lt;TResult&gt; مراجعه کنید.Custom schedulersبیشتر توسعه‌دهندگان برنامه یا کتابخانه نیازی به دانستن اینکه تسک روی کدام پردازنده اجرا می‌شود، چگونه کار خود را با سایر تسک‌ها هماهنگ می‌کند یا چگونه روی System.Threading.ThreadPool زمان‌بندی می‌شود، ندارند. آنها فقط نیاز دارند که تسک به‌طور کارآمد بر روی کامپیوتر میزبان اجرا شود. اگر نیاز به کنترل دقیق‌تری بر جزئیات زمان‌بندی دارید، TPL به شما این امکان را می‌دهد که برخی تنظیمات را روی زمان‌بند پیش‌فرض تسک پیکربندی کنید و حتی به شما اجازه می‌دهد که یک زمان‌بند سفارشی ارائه دهید. برای اطلاعات بیشتر، به TaskScheduler مراجعه کنید.Related data structuresث TPL چندین نوع جدید عمومی را فراهم می‌کند که در سناریوهای موازی و ترتیبی مفید هستند. این شامل. چندین کلاس مجموعه thread-safe، سریع و مقیاس‌پذیر در فضای نام System.Collections.Concurrent و چندین نوع همگام‌سازی جدید است. برای مثال، System.Threading.Semaphore و System.Threading.ManualResetEventSlim که برای برخی از انواع بارها کارآمدتر از نسخه‌های قبلی خود هستند. انواع جدید دیگر در .NET Framework 4، مانند System.Threading.Barrier و System.Threading.SpinLock، عملکردهایی را فراهم می‌کنند که در نسخه‌های قبلی موجود نبودند. برای اطلاعات بیشتر، به ساختار داده‌ها برای برنامه‌نویسی موازی مراجعه کنید.Custom task typesما توصیه می‌کنیم که از کلاس‌های System.Threading.Tasks.Task یا System.Threading.Tasks.Task&lt;TResult&gt; ارث‌بری نکنید. به‌جای آن، توصیه می‌کنیم که از ویژگی AsyncState برای ارتباط دادن داده‌ها یا وضعیت اضافی با شیء Task یا Task&lt;TResult&gt; استفاده کنید. همچنین می‌توانید از متدهای افزونه برای گسترش عملکرد کلاس‌های Task و Task&lt;TResult&gt; استفاده کنید. برای اطلاعات بیشتر در مورد متدهای افزونه، به متدهای افزونه مراجعه کنید.رفرنس : https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-based-asynchronous-programming </description>
                <category>Farhad Nosrati فرهاد نصرتی</category>
                <author>Farhad Nosrati فرهاد نصرتی</author>
                <pubDate>Mon, 03 Feb 2025 15:00:34 +0330</pubDate>
            </item>
                    <item>
                <title>همزمانی vs مواردی سازی</title>
                <link>https://virgool.io/@farhadnosrati/%D9%87%D9%85%D8%B2%D9%85%D8%A7%D9%86%DB%8C-vs-%D9%85%D9%88%D8%A7%D8%B1%D8%AF%DB%8C-%D8%B3%D8%A7%D8%B2%DB%8C-fmy4w4lczxv2</link>
                <description>همزمانی vs مواردی سازیهمان‌طور که راب پایک (یکی از سازندگان زبان Go) گفته است: هم‌زمانی یعنی رسیدگی به چندین کار به‌طور هم‌زمان.موازی‌سازی یعنی انجام چندین کار به‌صورت هم‌زمان.هم‌زمانی (Concurrency)هم‌زمانی به این معناست که یک برنامه هم‌زمان در حال پیشبرد چندین وظیفه است. اگر کامپیوتر فقط یک پردازنده (CPU) داشته باشد، ممکن است برنامه نتواند چندین وظیفه را دقیقاً در یک لحظه انجام دهد، اما وظایف به طور هم‌زمان در داخل برنامه در حال پردازش هستند. این بدین معناست که برنامه، بدون اینکه یک وظیفه را کاملاً به پایان برساند، وظیفه دیگری را شروع می‌کند.برای توضیح بهتر، می‌توان مثالی از زندگی واقعی زد: چالشی وجود دارد که شما باید هم یک کیک بزرگ را بخورید و هم یک آهنگ کامل بخوانید. شما برنده می‌شوید اگر بتوانید سریع‌تر از دیگران هم کیک را بخورید و هم آهنگ را به پایان برسانید. قانون این است که باید هم‌زمان کیک بخورید و آهنگ بخوانید، اما چگونگی انجام این کار به خود شما بستگی دارد. می‌توانید ابتدا کل کیک را بخورید و بعد کل آهنگ را بخوانید، یا می‌توانید نصف کیک را بخورید و نصف آهنگ را بخوانید و این روند را تکرار کنید.هم‌زمانی به این معناست که چندین وظیفه به طور هم‌زمان اجرا می‌شوند، اما نه الزاماً به صورت فیزیکی و همزمان. در یک پردازنده تک‌هسته‌ای، CPU تصمیم می‌گیرد که کدام وظیفه را ابتدا اجرا کند، یا ممکن است بخشی از یک وظیفه و سپس بخشی از وظیفه دیگر را اجرا کند. دو وظیفه می‌توانند هم‌زمان شروع شوند، اجرا شوند و به پایان برسند، به این معنا که وظیفه دوم ممکن است قبل از اتمام وظیفه اول شروع شود. این موضوع بستگی به معماری سیستم دارد. به طور خلاصه، هم‌زمانی به معنای اجرای چند وظیفه به طور هم‌زمان است، اما نه الزاماً به صورت همزمان واقعی.موازی‌سازی (Parallelism)موازی‌سازی به این معناست که یک برنامه وظایف خود را به وظایف کوچک‌تری تقسیم می‌کند که می‌توانند به صورت موازی پردازش شوند، مثلاً روی چندین پردازنده به طور همزمان.موازی‌سازی نیاز به وجود دو وظیفه مجزا ندارد. بلکه ممکن است بخش‌های مختلف یک وظیفه یا چندین وظیفه به طور هم‌زمان اجرا شوند. این کار با استفاده از معماری چند‌هسته‌ای CPU انجام می‌شود، به طوری‌که هر هسته به یک وظیفه یا زیر وظیفه اختصاص داده می‌شود.اگر به مثال قبلی بازگردیم، این بار همچنان قانون این است که شما باید هم‌زمان بخوانید و کیک بخورید، اما این بار شما در یک تیم دو نفره بازی می‌کنید. احتمالاً شما کیک را می‌خورید و دوستتان آهنگ می‌خواند (چون او بهتر می‌خواند و شما بهتر کیک می‌خورید). بنابراین این بار وظایف واقعاً به طور هم‌زمان انجام می‌شوند و این همان موازی‌سازی است.موازی‌سازی به سخت‌افزاری با چندین واحد پردازشی نیاز دارد. در یک پردازنده تک‌هسته‌ای ممکن است هم‌زمانی وجود داشته باشد، اما موازی‌سازی نخواهد بود. موازی‌سازی نوع خاصی از هم‌زمانی است که در آن وظایف واقعاً به طور هم‌زمان اجرا می‌شوند.تفاوت بین برنامه‌نویسی موازی و برنامه‌نویسی هم‌زمانحال بیایید تفاوت‌های اصلی بین هم‌زمانی و موازی‌سازی را فهرست کنیم. به عنوان مثال، کتاب &quot;هنر هم‌زمانی&quot; این تفاوت را به این صورت تعریف می‌کند:یک سیستم زمانی هم‌زمان گفته می‌شود که بتواند از دو یا چند عملیات به صورت هم‌زمان پشتیبانی کند. یک سیستم زمانی موازی گفته می‌شود که بتواند از دو یا چند عملیات به صورت همزمان (فیزیکی) پشتیبانی کند.مفهوم کلیدی و تفاوت اصلی بین این تعاریف، عبارت &quot;در حال پیشرفت&quot; است. این تعریف می‌گوید که در سیستم‌های هم‌زمان، چندین عملیات می‌توانند به طور هم‌زمان در حال پیشرفت باشند (اما الزاماً اجرا نمی‌شوند). در حالی که در سیستم‌های موازی، چندین عملیات به طور هم‌زمان اجرا می‌شوند. در واقع، هم‌زمانی و موازی‌سازی از نظر مفهومی تا حدی هم‌پوشانی دارند، اما عبارت &quot;در حال پیشرفت&quot; آن‌ها را متمایز می‌کند.هم‌زمانی به معنای پردازش هم‌زمان چندین وظیفه است. موازی‌سازی به معنای اجرای هم‌زمان چندین وظیفه است.یک برنامه می‌تواند هم‌زمان باشد اما موازی نباشد، یعنی چندین وظیفه را هم‌زمان پردازش کند، اما هیچ دو وظیفه‌ای به طور همزمان (فیزیکی) اجرا نشوند.یک برنامه می‌تواند موازی باشد اما هم‌زمان نباشد، یعنی چندین زیر وظیفه از یک وظیفه را به طور هم‌زمان در یک پردازنده چند‌هسته‌ای اجرا کند.یک برنامه می‌تواند نه موازی باشد و نه هم‌زمان، یعنی تمام وظایف را به صورت ترتیبی، یکی پس از دیگری پردازش کند.یک برنامه می‌تواند هم موازی و هم هم‌زمان باشد، یعنی چندین وظیفه را به طور هم‌زمان و به طور فیزیکی روی یک CPU چند‌هسته‌ای اجرا کند.</description>
                <category>Farhad Nosrati فرهاد نصرتی</category>
                <author>Farhad Nosrati فرهاد نصرتی</author>
                <pubDate>Wed, 02 Oct 2024 21:18:25 +0330</pubDate>
            </item>
                    <item>
                <title>IHttpClientFactory</title>
                <link>https://virgool.io/@farhadnosrati/ihttpclientfactory-aqkklgc8qpyk</link>
                <description>When you call any of the AddHttpClient extension methods, you&#x27;re adding the IHttpClientFactory and related services to the IServiceCollection.Manages the caching and lifetime of underlying HttpClientHandler instances. Automatic management avoids common Domain Name System &#40;DNS&#41; problems that occur when manually managing HttpClient lifetimes.Each time CreateClient is called:A new instance of HttpClient is created.The configuration action is called.Provide a single location to configure and interact with a particular HttpClient. For example, a single typed client might be used:For a single backend endpoint.To encapsulate all logic dealing with the endpoint.The typed client is registered as transient with DI.Using typed clients in singleton services can be dangerous .Avoid typed clients in singleton servicesHttpClient lifetime managementA new HttpClient instance is returned each time CreateClient is called on the IHttpClientFactory. One HttpClientHandler instance is created per client name.The factory manages the lifetimes of the HttpClientHandler instances.IHttpClientFactory caches the HttpClientHandler instances created by the factory to reduce resource consumption. An HttpClientHandler instance may be reused from the cache when creating a new HttpClient instance if its lifetime hasn&#x27;t expired.Caching of handlers is desirable as each handler typically manages its own underlying HTTP connection pool. Creating more handlers than necessary can result in socket exhaustion and connection delays. Some handlers also keep connections open indefinitely, which can prevent the handler from reacting to DNS changes.The default handler lifetime is two minutes. To override the default value, call SetHandlerLifetime for each client, on the IServiceCollection:services.AddHttpClient(&quot;Named.Client&quot;).SetHandlerLifetime(TimeSpan.FromMinutes(5));HttpClient instances created by IHttpClientFactory are intended to be short-lived.As soon as a typed client instance is created, IHttpClientFactory has no control over it. If a typed client instance is captured in a singleton, it may prevent it from reacting to DNS changes, defeating one of the purposes of IHttpClientFactory.Recycling and recreating HttpMessageHandler&#x27;s when their lifetime expires is essential for IHttpClientFactory to ensure the handlers react to DNS changes. HttpClient is tied to a specific handler instance upon its creation, so new HttpClient instances should be requested in a timely manner to ensure the client will get the updated handler.Disposing of such HttpClient instances created by the factory will not lead to socket exhaustion, as its disposal will not trigger disposal of the HttpMessageHandler. IHttpClientFactory tracks and disposes of resources used to create HttpClient instances, specifically the HttpMessageHandler instances, as soon their lifetime expires and there&#x27;s no HttpClient using them anymore.reference : https://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factoryhttps://www.linkedin.com/posts/farhad-nosrati-%D9%81%D8%B1%D9%87%D8%A7%D8%AF-%D9%86%D8%B5%D8%B1%D8%AA%DB%8C-231b84185_ihttpclientfactory-when-you-call-any-of-activity-7106673689277911040-Y7CE?utm_source=share&amp;utm_medium=member_desktop</description>
                <category>Farhad Nosrati فرهاد نصرتی</category>
                <author>Farhad Nosrati فرهاد نصرتی</author>
                <pubDate>Fri, 29 Sep 2023 21:23:03 +0330</pubDate>
            </item>
                    <item>
                <title>توضیحات chatGTP در مورد solid .</title>
                <link>https://virgool.io/@farhadnosrati/%D8%AA%D9%88%D8%B6%DB%8C%D8%AD%D8%A7%D8%AA-chatgtp-%D8%AF%D8%B1-%D9%85%D9%88%D8%B1%D8%AF-solid-vwm2rk6eikt5</link>
                <description>SOLID :یک مجموعه‌ی اصول طراحی شیءگرا است که برای ساختاردهی بهتر و قابل گسترش‌تر کردن کد، معرفی شده است. این اصول، به صورت خلاصه به صورت زیر هستند:Single Responsibility Principle (اصل مسئولیت تکی): هر کلاس باید فقط یک مسئولیت داشته باشد و باید تنها به یک دلیل برای تغییر مورد نیاز باشد.Open/Closed Principle (اصل باز/بسته): کد باید برای تغییرات بسته باشد ولی برای افزودن قابل باز باشد.Liskov Substitution Principle (اصل جایگزینی لیسکوف): هر شیء از یک کلاس، باید بتواند به عنوان یک شیء ازکلاس پدرش استفاده شود، بدون اینکه برنامه تغییر کند.Interface Segregation Principle (اصل جداسازی رابط): کلاس‌ها نباید از روش‌هایی که نیاز ندارند استفاده کنند و نباید به کلاس‌های دیگر وابسته باشند.Dependency Inversion Principle (اصل وابستگی معکوس): باید به جای وابستگی به جزئیات پیاده‌سازی، به ابسترکشن‌ها و رابط‌ها وابسته باشیم و وابستگی‌های بین کلاس‌ها را به صورتی طراحی کنیم که برای تغییرات کمتری در کد نیاز باشد.اصول SOLID به صورت جداگانه و در کنار یکدیگر، به ما کمک می‌کنند که کدی را را طراحی کنیم که قابلیت گسترش و تغییرات بیشتری داشته باشد و عملکرد بهتری داشته باشد. در ادامه، به توضیح هر یک از این اصول می‌پردازیم:Single Responsibility Principle: این اصل بیان می‌کند که هر کلاس فقط باید یک مسئولیت داشته باشد. به این صورت که هر کلاس باید فقط برای یک کار خاص طراحی شود و اگر برای کار دیگری نیاز به تغییرات داشته باشد، باید از آن کلاس جدا شود. به طور مثال، در یک برنامه مدیریت فروشگاه، دو کلاس مجزا برای مدیریت محصولات و مدیریت سفاردهی باید طراحی شوند، به جای آنکه هر دو مسئولیت در یک کلاس قرار داشته باشد.Open/Closed Principle: این اصل بیان می‌کند که کد باید برای تغییرات بسته باشد ولی برای افزودن قابل باز باشد. به این صورت که باید بتوانیم قابلیت‌های جدید به برنامه خود اضافه کنیم، بدون اینکه کد قبلی را تغییر دهیم. به طور مثال در یک برنامه بازی، باید بتوانیم شخصیت‌های جدید را به بازی اضافه کنیم، بدون اینکه کد اصلی بازی را تغییر دهیم.Liskov Substitution Principle: این اصل بیان می‌کند که هر شیءاز یک کلاس، باید بتواند به عنوان یک شیء از کلاس پدرش استفاده شود، بدون اینکه برنامه تغییر کند. به عبارت دیگر، باید بتوانیم شیء‌های جدید را به برنامه خود اضافه کنیم، بدون اینکه تغییراتی در برنامه اصلی ایجاد شود. به طور مثال، در یک برنامه مدیریت حساب بانکی، باید بتوانیم بدون تغییر کد اصلی، حساب‌های جدید را به برنامه اضافه کنیم.Interface Segregation Principle: این اصل بیان می‌کند که کلاس‌ها نباید از روش‌هایی که نیاز ندارند استفاده کنند و نباید به کلاس‌های دیگر وابسته باشند. به عبارت دیگر، باید روش‌هایی که برای کاری لازم نیستند، در کلاس‌ها قرار نگیرند و هر کلاس فقط به آن چیزی که نیاز دارد، وابسته باشد. به طور مثال، در یک برنامه مدیریت فروشگاه، کلاس مدیریت محصولات نباید از روش‌هایی که برای سفارش‌ها نیاز داریم استفاده کند.Dependency Inversion Principle: این اصل بیان می‌کند که باید به جای وابستگی به جزئیات پیاده‌سازی، به ابسترکشن‌ها و رابط‌ها وابسته باشیم و وابستگی‌های بین کلاس‌ها را به صورتی طراحی کنیم که برایتغییرات کمتری در کد نیاز باشد. به عبارت دیگر، باید به جای استفاده از قطعات کد و جزئیات پیاده‌سازی، از رابط‌ها و ابسترکشن‌ها استفاده کنیم تا بتوانیم وابستگی‌های بین کلاس‌ها را به صورت مناسبی طراحی کنیم. به طور مثال، در یک برنامه مدیریت سفارش‌ها، باید از رابط‌ها برای ارتباط بین کلاس‌های مدیریت محصولات، مدیریت مشتریان و مدیریت پرداخت‌ها استفاده کنیم.</description>
                <category>Farhad Nosrati فرهاد نصرتی</category>
                <author>Farhad Nosrati فرهاد نصرتی</author>
                <pubDate>Sun, 21 May 2023 14:35:55 +0330</pubDate>
            </item>
                    <item>
                <title>تفاوت بین : DI (Dependency Injection) و  IoC (Inversion of Control) و  DI Container (Dependency Injection Container)</title>
                <link>https://virgool.io/@farhadnosrati/%D8%AA%D9%88%D8%B6%DB%8C%D8%AD%D8%A7%D8%AA-chatgpt-%D8%AA%D9%81%D8%A7%D9%88%D8%AA-%D8%A8%DB%8C%D9%86-di-dependency-injection-%D9%88-ioc-inversion-of-control-%D9%88-di-container-dependency-injection-container-bi3uaznglyzy</link>
                <description>همه‌ی این الگوهای برنامه‌نویسی، مربوط به مفهوم Dependency Injection هستند که در زبان‌های برنامه‌نویسی مختلف مورد استفاده قرار می‌گیرند.در الگوی DI (Dependency Injection)، مسئولیت ایجاد شیء وابستگی‌های آن به دسترسی به دیگر شیء‌ها را به یک سرویس‌گیرنده (Service Consumer) منتقل می‌کنیم. به این صورت که به جای اینکه سرویس‌گیرنده خودش شیء مورد نیازش را ایجاد کند، آن شیء را از طریق پارامترهایی که به متد سازنده یا متد‌های دیگر ماژول ارسال می‌کنیم، دریافت می‌کند.درالگوی IoC (Inversion of Control)، کنترل اجرای برنامه از دست برنامه‌نویس خارج شده و به یک کتابخانه یا چارچوب نرم‌افزار مانند Spring Framework و Unity Container منتقل شده است. در این الگو، کتابخانه یا چارچوب نرم‌افزار برای مدیریت تمامی اجزای برنامه و ایجاد اتصالات بین آنها و اجرای لازم برنامه مسئولیت دارد.در الگوی DI Container (Dependency Injection Container)، یک کتابخانه یا چارچوب نرم‌افزار برای مدیریت و ایجاد شیء‌هایی که به یکدیگر وابسته هستند مسئولیت دارد. این الگو به برنامه‌نویس این امکان راهداف مربوط به توسعه‌ی اپلیکیشن، برای رسیدن به یک نتیجه‌ی مشخص و مطلوب، تعریف می‌شود و شامل چندین مرحله است. برخی از اهداف مهم توسعه‌ی اپلیکیشن عبارتند از:برآوردن نیازهای کاربران: یکی از مهم‌ترین اهداف توسعه‌ی اپلیکیشن، برآوردن نیازهای کاربران است. برای رسیدن به این هدف، تیم توسعه‌ی باید با کاربران و مشتریان برای درک نیازهای آن‌ها ارتباط برقرار کند و بر اساس آن، ویژگی‌ها و امکانات مورد نیاز را در اپلیکیشن پیاده‌سازی کند.ارائه‌ی یک راه حل مناسب: برای رسیدن به این هدف، تیم توسعه‌ی باید برای پیاده‌سازی اپلیکیشن، یک راه حل مناسب و بهینه ارائه دهد. برای این کار، تیم توسعه‌ی باید با تکنولوژی‌های جدید و به‌روز آشنا باشد و بر اساس نیازهای اپلیکیشن، از آن‌ها استفاده کند.افزایش کیفیت و کارایی: یکی از اهداف مهم توسعه‌ی اپلیکیشن، افزایش کیفیت و کارایی آن است. برای رسیدن به این هدف، تیم توسعه‌ی باید از بهترین روش‌های پیاده‌سازی و با استفاده از اصول و مفاهیم به‌روز استفاده کند. الگوی DI Container به برنامه‌نویس این امکان را می‌دهد تا با استفاده از یک کتابخانه یا چارچوب نرم‌افزار، کد خود را به صورت ماژولار پیاده‌سازی کند و برای ایجاد اتصالات بین اجزای مختلف برنامه از Dependency Injection استفاده کند. در این الگو، کتابخانه یا چارچوب نرم‌افزار برای مدیریت و ایجاد شیء‌هایی که به یکدیگر وابسته هستند مسئولیت دارد و برنامه‌نویس می‌تواند با استفاده از این الگو، کد خود را به صورت قابل و ماژولار پیاده‌سازی کند و برای ایجاد اتصالات بین اجزای مختلف برنامه از Dependency Injection استفاده کند. در این الگو، کتابخانه یا چارچوب نرم‌افزار برای مدیریت و ایجاد شیء‌هایی که به یکدیگر وابسته هستند مسئولیت دارد و برنامه‌نویس می‌تواند با استفاده از این الگو، کد خود را به صورت قابل توسعه و قابل انعطاف پیاده‌سازی کند.-----------------------DI یا Dependency Injection، IoC یا Inversion of Control و Container یا DI Container هر سه مفهوم مستقل و مختلفی هستند، اما با هم ارتباط دارند:Dependency Injection (DI):DI به معنی تزریق وابستگی‌ها است و به این معنی است که یک شیء می‌تواند وابستگی‌های خود را به جای این که خودش آن‌ها را ایجاد کند، به شیء دیگری با این وظیفه بسپارد. به عبارت دیگر، شیء مورد نظر خودش نمی‌تواند وابستگی‌های خود را بسازد، بلکه آن‌ها را از منابع خارجی دریافت می‌کند.Inversion of Control (IoC):IoC به معنی برعکس کردن کنترل است و به این معنیاست که کنترل اجرای برنامه از سمت شیء اصلی به شیء دیگری منتقل می‌شود. در IoC، شیء اصلی کنترل برنامه را به جای آن که خودش کد را اجرا کند، به شیء دیگری منتقل می‌کند. به عبارت دیگر، در IoC، شیء اصلی برای اجرای کد خود به شیء دیگری وابسته می‌شود.DI Container:DI Container یا اینورتر کنترل به عنوان یک container برای مدیریت وابستگی‌های یک برنامه استفاده می‌شود. این کانتینر قادر است که وابستگی‌های موجود در یک برنامه را مدیریت کند و در زمان لازم آن‌ها را به شیء‌های دیگر تزریق کند. بدین ترتیب، DI Container با استفاده از مکانیزم DI، کنترل اجرای برنامه را تغییر می‌دهد و به جای این که شیء اصلی وابستگی‌های خود را ایجاد کند، از DI Container برای دریافت وابستگی‌های خود استفاده می‌کند.به طور خلاصه، Dependency Injection (DI) و Inversion of Control (IoC) دو مفهوم مستقل و مختلف هستند، که هر دو به منظور کاهش وابستگی‌های بین کلاس‌ها و ماژول‌های یک برنامه استفاده می‌شوند. در حالی که DI Container به عنوان یک container برای مدیریت وابستگی‌های یک برنامه استفاده می‌شود و با استفاده ازمکانیزم DI، وابستگی‌ها را در زمان اجرای برنامه تزریق می‌کند. به عبارت دیگر، DI Container یک ابزار است که به شیء اصلی کمک می‌کند تا وابستگی‌های خود را مدیریت کند و به شیء‌های دیگر تزریق کند.</description>
                <category>Farhad Nosrati فرهاد نصرتی</category>
                <author>Farhad Nosrati فرهاد نصرتی</author>
                <pubDate>Sun, 21 May 2023 13:28:35 +0330</pubDate>
            </item>
                    <item>
                <title>concurrency and parallelism</title>
                <link>https://virgool.io/@farhadnosrati/concurrency-and-parallelism-tefqc2ge3jv8</link>
                <description>concurrency and parallelismfirst thing is concurrency and parallelism this sounds kind of a similar but they are not concurrency basically means that you execute things that are overlapping in time so you could have two or three any number of things executing and there seem to be executing at the same time but not necessarily they are happening in parallel so in order to do parallelism then you have you can execute multiple processes or have multiple threads right if you have a multi-core system Hardware then they could execute literally at the same time so what is the process and what is a thread basically there are many resources that on the internet that define them very well and they are also goods etc but here I will I will give you a very quick summary basically both are independent flows of execution in a in a program let&#x27;s say but a process is at the program level and a threat is inside the process right so you can have multiple processes in each of the process having multiple threads up thread of a process share the memory thesame memory space so if you have different processes they will have their own memory space but if you have a thread like all the threads inside the process will share them the same memory space and that has some connotations where you are tackling concurrency when programming using multiple threadsthen it&#x27;s called multi-threading programming .multi-threading programming can be very useful for your program because it will allow you to execute things in parallel and so times improved efficiency or the execution time of your program it&#x27;s verytricky sometimes to know how many threads you should use and it would depend a lot on your use case on the programming languages are you using on the operating system the machine that you are then used in basically if you really really want to have an optimized the most optimized version you need todo benchmarking and check what is improving or not the performance of your applicationduring general there are different roles that allow you to more or less have an idea at least how to discuss the performance of your program if you want to do a concurrency or if you want toimplement multi-threaded solution traditional rule of thumb is to have as many threads of course have your hardware machine right and this is a rule of thumb but it&#x27;s it&#x27;s not always the way to go that&#x27;s a because you can have things for example that execute always sequentially right so even if youhave four core or eight cores or how many cores you will need still to execute things sequentially you are not going to do better having four or eight threat versus having only one there are also other cases where you&#x27;re doing a lot of calculations that can be wrong in powering in which case you cannot domore calculations that the CPU allows you at the same time so if you have four cores then you will have probably four threads executing calculations on all of them but also if you have IO or input I would operations during those times the CPU is going to be idle so it doesn&#x27;t matter if you only have four threads in the four of them are doing I all like waiting for the t-score doing a requested data base or resolving a request from a user on the web server then the CPU is going to be either in those cases so in n that case might be useful to have more threats than the CPU cores because you will be able to alwayshave a tray that is executing something if you have to feel or too many threads your application can run significantly slower so it&#x27;s very important to have this kind of reflection when you are thinking about doing things concurrently or and this is something very important to have when you&#x27;re discussing with your teammates when you are a new solution and you want to define what is going to be the best way to optimize your server for example or your application it&#x27;s good to have these kind of discussions but of course it&#x27;s also very important or anything like an interviews if you need to you know think about these topics right like why you&#x27;re taking one decision versus another what is going to be the performance impact of doing something versus another in terms of concurrency so that&#x27;s it for today.Thank you very much for Reade and if you liked the Article don&#x27;t  forget to click the like button, follow, share it. And if I missed something, or you want  me to explain something a little bit better don&#x27;t forget to mention it in the comments.</description>
                <category>Farhad Nosrati فرهاد نصرتی</category>
                <author>Farhad Nosrati فرهاد نصرتی</author>
                <pubDate>Tue, 26 Jul 2022 18:51:24 +0430</pubDate>
            </item>
                    <item>
                <title>software architecture and design (part 1)</title>
                <link>https://virgool.io/@farhadnosrati/software-architecture-and-design-volez1uivtcg</link>
                <description>software architecture and designatchitecture (part 1)In this series of Article I will be covering many concepts and fundamentals of software architecture so hopefully by the end of it you will be more prepared to tackle software  design challenges, have better discussions  and even be more prepared for a technical  interview.So without further ado let&#x27;s start Software architecture has many definitions one  of the most famous one is from Ralph Johnson  where he says: &quot;architecture is about  the important stuff, whatever that is&quot;  but...what is important stuff? In the  software architecture we focus more on the  structure more than implementation details.Software architecture is also about making  the expensive choices that are costly to change  after they are implemented.It&#x27;s also about making explicit the core decisions that will allow  the software to have high quality.Concepts are better understood in practice, so let&#x27;s  build an e-commerce site and see how that looks.So, for example in our e-commerce site we need to allow our users to do certain things like search the inventory, check reviews, buy a product, review past orders and maybe other features as well.These are the functional requirements  of the application. Besides of what the system  should do we also need to focus on how should  the system behave.These are also called the  non-functional requirements.These are sometimes  defined as the &quot;-ilities&quot; that the system can have  like: functionality, reliability, usability,  efficiency, these kind of things. For example,  in our e-commerce site let&#x27;s say that we wanted it  to be maintainable for several years and this is  a maintainability requirement; we also want to be  able to serve millions of users: in this case it&#x27;s  scalability; we also want to make it available  24/7: which is a reliability to make sure that the  system is very stable.We also want to have good  response latency: which is efficiency; and we can  have many others.Finally, besides functional  and non-functional requirements you may also have additional restrictions that will limit the  options that you will have for your architecture.So, for example, we could have some legal  compliance, costs, time to market, standards, etc.several restrictions that will limit the number  of options that we will have to design our system. Let&#x27;s say in our e-commerce site we need  to comply with the European Privacy Law:GDPR.So, with that we need to take into  consideration architecture how to handle that.So after you get the context, you know all  the things that the system needs to do,how it should behave and what restrictions are in  place that you need to take into consideration. So  after you have all of these things, you need  to prioritize them.Some requirements and  restrictions will conflict between them.For  example, if you have a strict time to market,  maybe you need to drop some features.There  can also be other things like non-functional  requirements that need to be prioritized.So for  example, in our case of the e-commerce site, we  might not care too much about portability because  we will have a strong control of where it&#x27;s going to be deployed the application and after it&#x27;s  deployed in there we don&#x27;t plan to move it to other platforms. So we could drop portability in  favor of scalability or maintainability. So after you have prioritized the list and you have made  this trade-off you need to think about if it&#x27;s acceptable or not so after it&#x27;s acceptable  then you start designing the architecture. How do you start designing the system? So the  first thing is once you have it prioritized start with one important thing at a time. If you try  to tackle everything at the beginning and trying to think about all the possible scenarios in the  future, you might end up having an over-engineered solution and this is not good because it is an  unnecessarily complex system. There is also an acronym for that is YAGNI: You Ain&#x27;t Going to Need  It. So if you are not sure about something or if it&#x27;s not prioritized then try not to tackle at  first. Try to postpone it to when you have better context and can make a better decision about it.  Now that you have this you might start thinking about what are the possible architectures that  might fit your system. For that, a good book that I recommend and that is useful for me, is  this free ebook from O&#x27;Reilly that is: &quot;Software Architecture Patterns&quot;. It is a good book to get  a grasp of different architectural approaches and you can see several architectural patterns  like: Layered, Event Driven, Microkernel, Microservices and Space based. This book shows pros and cons  of each of these patterns and might help you at  the beginning when you&#x27;re designing the system  what to look for and what would be best for your system based on your current requirements. So we  have decided what are some of the features that we want to have our system implemented.We have  also mentioned that maintainability is one of the non-functional requirements that is very important  for us, so with that we can start designing our system and we can take for example a Layered  approach. We could have a Database or a Storage Layer where we would sort data; then we will  have a Logic Layer where we will have the backend servers that will be taking care of handling  any business logic that we want to handle; and then the Visualization part or UI, where we&#x27;ll  be allowing the users to interact with the system and this is how we get to the Layered Architecture So here we have defined the architecture  with the structure that the system will have. The features can then be implemented following  this layered architecture. And if you want to learn a little bit more about how to implement the  features in a scalable nice way then I recommend you to check out my other video about design  patterns. It&#x27;s very typical in web applications to use a layered architecture but it&#x27;s not the  only architectural pattern that we can use. There is no silver bullet so make sure that in  your context you look to different approaches and pick the architecture pattern that would better  fit your use case. It&#x27;s also normal that the architecture would evolve over time and sometimes  even in unintended ways that would make expensive changes to the architecture. So you need to make  a balance about foreseeing the certain things that you will need to cover versus the things  that you need to prioritize in the short term.If you try to tackle everything then you can  end up having an overengineered solution.One of the most expensive things can be scaling. So, in our case, we already have the architecture: How can we make it scale to serve  millions and millions of user requests? For that check out my next Article. And  that&#x27;s it for today! Thank you very much for Reade and if you liked the Article don&#x27;t  forget to click the like button, follow, share it. And if I missed something, or you want  me to explain something a little bit better don&#x27;t forget to mention it in the comments.</description>
                <category>Farhad Nosrati فرهاد نصرتی</category>
                <author>Farhad Nosrati فرهاد نصرتی</author>
                <pubDate>Tue, 26 Jul 2022 18:48:38 +0430</pubDate>
            </item>
                    <item>
                <title>Asynchronous programming</title>
                <link>https://virgool.io/@farhadnosrati/asynchronous-programming-qq3v8v5iurpr</link>
                <description>قبل شروع یک rollback بزنیم به Synchronous programming .در این نوع programming برنامه Sequential  اجرا میشه یعنی ؟نرم افزار بر روی یک thread  اجرا شده و clr شروع میکند خط به خط کد ها را اجرا کردن و اگر خط قبلی اجرا نشود هیچوقت خط بعدی اجرا نخواهد شد .اشکال : اگر اجرای یک خط کد ۱۰ ثانیه زمان ببرد ، چون عملیات فوق (عملیات ۱۰ ثانیه ) بر روی thread اصلی نرم افزار ( main thread )  اجرا شده است ، نرم افزار تا اتمام آن خط در همان حالت و وضعیت منتظر میماند تا ۱۰ ثانیه به پایان برسد بعد وارد خط بعدی شود .مثلا فرض کنید اگر ما یک عملیات زمانبری داشته باشیم مثل گذارش گیری ماهانه یا قرار باشد همزمان علاوه بر گذارش گیری چند عملیات دیگر هم انجام دهیم ، در این شرایط انجام عملیات همزمان ( parallel ) غیر ممکن است چون عملیات گذارشگیری بر روی  main thread نرم افزار اجرا شده ، در این شرایط نه تنها عملیات دیگری نمیتواند اجرا شود بلکه  کل نرم افزار صبر میکند تا عملیات اول ( گذارشگیری ) به اتمام برسد بعد وارد عملیات بعدی شود  .ما نیاز داریم نرم افزار ، همزمان با گذارشگیری ، عملیات دیگری هم اجرا کند . اینجاست که باید برویم سراغ Asynchronous programming :در Asynchronous programming نرم افزار ما در شرایط ذکر شده صبر نمیکند و میتواند همزمان با گذارش گیری ، عملیات های دیگری هم اجرا کند .  سوال : چگونه این اتفاق شدنیست ؟ این سوال مربوط  به multi threading  است ولی در این متن تصميم ندارم وارد مباحثش شوم ولی توضیح مختصری ازش میگویم که گوشیه زهنمان باشد .سی پی یو cpu چند هسته ای هست و هر هسته از چندین thread تشکیل شده که ما میتونیم برای این که سرعت و کارایی نرم افزارمان را بالا ببریم و از تمام قدرت cpu برای اجرای نرم افزارمان استفاده کنیم .چون یک thread نمیتواند بیشتر از یک process را هندل کند ، میتوانیم جدا از main thread  ، از thread های دیگر cpu به طور مستقل از هم و همزمان استفاده‌ کنیم .نکته : در حالت multi threading نباید چند عملیات که همزمان اجرا میشوند به هم وابسته باشند چون اگر اجرا شدن متدی ، وابسته به نتیجه ( return ) متد دیگر باشد ، خطا رخ میدهد و برای این نوع عملیات حتما باید صبر کرد .کاربرد اصلی Asynchronous این است که نرم افزار منتظر نمیماند به این شکل که main thread نرم افزار را آزاد میکنیم و برای هر عملیات یک thread دیگر و مستقل تخصیص میدهیم .دو کلمه کلیدی Async awayt :Async :  این کلمه کلیدی در ابتدای متد اعلام میکرد که متد جاری یک متد از نوع Asynchronous است ‌.توجه : در اتمام نام متد های Asynchronous حتما باید با  Async پایان یابد که زمان خوانده نام متد ، مشخص شود این متد یک متد Asynchronous است .مثل نام متد زیر :GetCarNameAsync();وقتی متدی از نوع Async تعریف می شود باید از یک سری قوانین تبعیت کند :متدی که از نوع Async است حتما باید یک Task را اجرا کند و خروجی از نوع Task  برگرداند که میتواند یک Task از نوع T باشد .به شکل زیر :Task  Task&lt;T&gt; ==&gt; Task&lt;int&gt; , Task&lt;string&gt; voidیک task میتواند اجرای یک یا چند thread  باشد که وقتی یک متد  async اجرا میشود در واقع clr آن را در یک thread مستقل و همزمان با thread های دیگر و در background اجرا میکند .نکته:  توجه داشته باشید که یک thread  نمیتواند مقدار بازگشتی داشته باشد ولی Task میتوان و یک thread میتواند فقط یک process رو هندل کند ولی Task چندیدن کار را میتوند انجام دهد .البته همیشه و حتما معنای task در ابتدای متد ها به معنای run شدن آن متد در یک thread جدید نیست که جلوتر توضیحات کامل ارائه میشود . Await : اگر متدی در یک thread مستقل اجرا شود در واقع ، وقتی کامپایلر به بلاک آخر متد برسد آن thread بسته میشود و هیچ وقت از وضعیات عملیاش و در صورت بروز هر گونه خطا در زمان اجرا باخبر نخواهیم شد پس حتما برای متد های Async task صبر کنیم مگر در شرایط خواص .برای این کارمیتوانیم از کلمه کلیدی  await استفاده کنیم .این کلمه کلیدی این امکان را میدهد که ما در thread اجرا شده صبر کنیم و تا به پایان نرسیدن عملیات ،  thread بسته نشود .به مثال زیر توجه کنید :static async Task Main(string[] args)         {             var threadId = Thread.CurrentThread.ManagedThreadId;             Console.WriteLine(&quot;Main:&quot; + threadId);             await GettaskAsync();             threadId = Thread.CurrentThread.ManagedThreadId;             Console.WriteLine(&quot;Main:&quot; + threadId);             Console.ReadKey();         }         public static async Task GetTaskAsync()         {             var threadId = Thread.CurrentThread.ManagedThreadId;             Console.WriteLine(&quot;GettaskAsync:&quot; + threadId);             await Task.Delay(1000);             threadId = Thread.CurrentThread.ManagedThreadId;             Console.WriteLine(&quot;GettaskAsync:&quot; + threadId);         }شرح کد : متدی از نوع async به نام Main بر روی thread اصلی نرم افزارمان اجرا است ، وقتی کامپایلر بر روی await داخل متد Main میرسد ، با همان thread جاری وارد متد async فراخوان شده ( GetTaskAsync )  میشود و شروع به پردازش متد دوم میکند ، حال اگر در بدن متد فراخوان شده await داشته باشیم و به آن برسد ، در صورت این که پردازش آن Await زمان بر باشد و باعث معلق شدن نرم افزار یا thread اصلی شود ، در این لحضه thread اصلی ( جاری ) را آزاد کرده و یک thread جدید اجرا میکند و به صورت yield تا پایان عملیات به متد فراخوانی شده ما گوش میدهد و در زمان پایان عملیات thread جدید ، ادامه عملیات خود را با همان thread جدید ساخته شده ادامه داده و به متد اول باز می گردد ، که این کار یک روش . net ، برای جلوگیری از thread deadlock است .حال اگر در متد دوم ( thread دوم ) هم یک await باشد ، عملیات بالا را تکرار میکند .در این شرایط نرم افزار هنگ نمیکند چون این روش یک multi tasking بود و در دات نت ، async یک signature برای پیاده سازی multi tasking است .قطعا برنامه نویسی muti threading پیچیده است به همین دلیل .net با روش TAP این امکان را به ما میدهد که با استفاده از کلمات کلیدی async/await/Task کد های مشابه sync بنویسیم و کامپایلر زحمت تغییرش به multi threading برایمان بکشد .قوانین استفاده از async/await/Task :یک بار async و همواره async : • هیچوقت یک متد async را در یک متد sync فراخوان نکنید . برای متد های sync متد معادل sync توسعه دهید و برای متد های async متد های معادل async توسعه دهید و استفاده کنید .• هیچوقت از دستور .result و یا .wait استفاده نکنیند چرا که این کار باعث بروز deadlock شود . به کد زیر توجه کنید :public  string GetCarAsync()         {             return GetCarNameAsync():         }         public async Task&lt;string&gt; GetCarNameAsync()         {             await Task.Run(() =&gt; Task.Delay(1000));             return &quot;praid&quot;;         }شرح :امکان return نتیجه متد async در یک متد sync وجود ندارد چون متد async یک Task برمیگرداند . متن خطای کد بالا &quot;امکان تغییر string یه یک Task&lt;straing&gt; به روش implicit  وجود ندارد&quot; .  پس برای این که بتوانیم صورت مسئله را پاک کنیم ، از دستور .result در انتهای فراخوانی اضافه میکنیم تا مقدار result  (که مقدار string باشد) را از Task گرفته ( جداکرده ) و نتیجه یک string بازگرداند .return GetCarNameAsync().result; علت خطا : این کار باعث اجرا شدن عملیات async به روش sync میشود ولی همواره دو thread درگیر هندل کردن یک عملیات sync هستند ، در این شرایط دات نت thread را lock کرده و deadlock رخ میدهد  .پیشنهاد : استفاده از GetAwaitr().GetResult(); به جای دیتور .result. در شرایطی که ناچار به استفاده از متد async در متد sync شدید ، به جای دستور .result میتوانید از دستور زیر برای این کار استفاده کنید return GetCarNameAsync().GetAwaitr().GetResult();این دستور اجازه میدهد زمان بروز exception در thread ، به جای throw کردن aggregate exception ، میتواند exception را برگرداند .• دستور  Task.Run .متد Run به عنوان ورودی یک Delegate از نوع Action میگیرد و بلافاصله یک thread اجرا کرده و delegate دریافت کرده را در thread جدید اجرا می کند . پس به جز مواقع نیاز و ضروری ، از این دستور استفاده نکنیم چون یک thread از thread pool را اشغال میکند .نکته مهم : در صورت لزوم میتوانید ، به جای Task.Run از دستور Task.FromResult استفاده کنید ، با همان عملکرد و با این تفاوت که thread جدید اجرا نمیکند .توجه : ما به جای delegate action از lambda expression استفاده کرده ایم .به متد های زیر توجه کنید :public async Task&lt;string&gt; GetCarAsync()         {             return await GetCarNameAsync();         }         public async Task&lt;string&gt; GetCarNameAsync()         {  await Task.Run(() =&gt; Task.Delay(1000));             return &quot;praid&quot;;         }نکته : اگر برای دستور Task.Run مانند دستور بالا await استفاده کنید یعنی برایش صبر کنید ( مانند کد بالا)  ، clr برای اجرا شدن آن thread ، در همان line صبر میکند و بعد از پایان عملیات به خط بعدی میرود ولی اگر await نداشته باشد ، thread جدید ساخته و همزمان با thread اصلی در background اجرا میشود ، ولی با این تفاوت که clr منتظر پایان این thread نمیماند و بعد از اجرای خط Task.Run به خط بعدی میرود و همزمان thread جدید در backgroun اجرا است  .توجه : اگر متد خروجی نداشته باید فقط Task برمیگرداند پس به ۳ دلیل هیچگاه از دستور async Task void استفاده نکنید . 1 - در متد های async دیگر نمیتوانیم فراخوانی و await کنیم ، چون خروجی آن از نوع void است نه Task ، پس حتما نتیجه بازگشتی آن با Task متفاوت است و احتمال بروز dead lock در عملیات آن وجود دارد .نکته : استفاده از این روش در شرایط خیلی خواص و با دانش و اگاهی کامل از عملیاتی که در حال توسعه و پیاده سازی ان هستیم بلامانع است . 2- در متد async Task void اگر exception رخ دهد ، نمیتوانید آن را throw catch کنید چون نتیجه متد از نوع void است و مقداری بر نمیگرداند .دوستان عزیز ، خیلی ممنون که وقت گران قدرتونو گذاشتید و تا به اینجا همراهیم کردید .اگه اشتباه مفهومی داشتم یا ایراد تایپی داشتم یا ایراد توضیح داشتم خیلی خوشحال میشم بهم بگید تا اصلاح کنم .مخلصیم ...</description>
                <category>Farhad Nosrati فرهاد نصرتی</category>
                <author>Farhad Nosrati فرهاد نصرتی</author>
                <pubDate>Fri, 25 Feb 2022 15:57:30 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش IHttpClientFactory در DotNetCore</title>
                <link>https://virgool.io/@farhadnosrati/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-ihttpclientfactory-%D8%AF%D8%B1-dotnetcore-n1coattjo2l0</link>
                <description>سلام دوستان .آموزش کامل IHttpClientFactory رو تو کانال YouTube آپلود کردم ، از این لینک میتونید مستقیم برید برای دیدنش .فقط چند تا نکته رو فراموش کردم بگم که اینجا مینویسم .نکته که فراموش کردم بگم : مختصر : کلاس HttpClient یه کلاس thread safe هست به جز اون چهارتا property داخلش که thread safe نیست ( ینی اگه بین دوتا درخواست baseaddres رو عوض کنید کل درخواستاتون baseaddresش تغییر میکنه ) که میتونیم به صورت singleton تو کل نرم افزار استفاده کنیم ولی باز از تغییرات dns هاتون باخبر نمیشیم .لطفا و حتما نظرتونو برام بنویسید .مخلصیم ...</description>
                <category>Farhad Nosrati فرهاد نصرتی</category>
                <author>Farhad Nosrati فرهاد نصرتی</author>
                <pubDate>Wed, 16 Feb 2022 22:05:19 +0330</pubDate>
            </item>
                    <item>
                <title>static در #C ( سی شارپ  )</title>
                <link>https://virgool.io/@farhadnosrati/%D8%AA%D8%B9%D8%B1%DB%8C%D9%81-static-%D8%AA%D9%88-%D8%B3%DB%8C-%D8%B4%D8%A7%D8%B1%D9%BE-c-lhdjfy9ob0ig</link>
                <description>برای هر نوع پروسه‌ای که در آن بارگذاری می‌شود RAM به سه قسمت تقسیم می‌گردد : Stack ، Heap و Static (استاتیک در دات نت در حقیقت قسمتی از Heap است که به آن High Frequency Heap نیز گفته می‌شود ).این قسمت استاتیک حافظه، محل نگهداری متدها و متغیرهای استاتیک است. آن متدها و یا متغیرهایی که نیاز به نمونه سازی از کلاس برای ایجاد ندارند، به صورت استاتیک ایجاد می‌گردند. در سی شارپ از واژه کلیدی static برای معرفی آن‌ها کمک گرفته می‌شود. برای مثال:گفته شد که کامپایلر تضمین می کند هیچ شی ای (object) از نوع کلاس های استاتیک (static class) ساخته نشود و فراخوانی اعضای کلاس از طریق نام کلاس انجام می شود.کلاس استاتیک ( Static class )از دیدگاه کلی یک کلاس استاتیک (static class) مانند یک کلاس غیر استاتیک (none static class) است با همان بدنه و تعاریف ، هر چند در بین تعریف این دو نوع از کلاس (class) تفاوت ها یی وجود دارد :قبل از کلمه کلید class از کلمه کلیدی static استفاده می شود.از یک کلاس استاتیک (static class) نمی توان نمونه (instance) و یا شی (object) ایجاد کرد به عبارت دیگر استفاده از کلمه کلیدی new برای ایجاد و مقدار دهی متغیری (شی) از نوع  داده یک کلاس استاتیک(static class)  بی معنا است. در این نوع از کلاس  یعنی کلاس استاتیک (static class) برای دسترسی به اعضای کلاس (members) مانند ، فیلد ها (fields) و متد ها (methods) از نام کلاس استاتیک (static class)  استفاده می شود .مثال : فراخوانی یک متد (method) با دسترسی عمومی (public) در یک کلاس استاتیک (static class).● تمامی اعضای یک کلاس استاتیک (static class) از نوع استاتیک (static) هستند. در واقع یک کلاس استاتیک (static class) را می توان مخزنی از متد های استاتیکی (static methods) دانست که برای انجام عملی که به منظور انجام آن بوجود آمده اند تنها با پارامترهای ورودی خود ، کار می کنند .● کلاس استاتیک (static class)  مهر وموم شده (sealed) هستند در نتیجه نمی توان از انها ارث (inheritance) برد.● کلاس استاتیک (static class)  نمی تواند از هیچ  کلاسی ارث بری (inheritance) داشته باشند بجز کلاس object ( تمام کلاس ها به صورت مستقیم و غیر مستقیم از کلاس object ارث بری داند)● کلاس استاتیک (static class) نمی توانند سازنده (constructor )  غیر استاتیک داشته باشند البته  قطعا از سازنده استاتیک (static constructor) می توانند برای مقدار دهی متغیر های استاتیک خود استفاده کنندنکته : یک کلاس استاتیک (static class) مانند یک کلاس غیر استاتیک (none static class) با سازنده خصوصی (private constructor) است  که تمامی اعضای داده ای (data members) واعضای تابعی (functional members) در آن از نوع استاتیک (static) تعریف شده باشند. در این حالت سازنده  خصوصی (private constructor) می تواند تضمین کننده این باشد که هیچ شی ای از این  کلاس ساخته  نشود.  اما در مورد یک کلاس استاتیک (static class) این برتری  وجود دارد که کامپایلر تضمین می کند که هیچ شی ای (object) از یک کلاس استاتیک(static class) ساخته نمی شود، در کنار خصوصیات دیگری که در بالا از ان ها نام برده شد.اعضای استاتیک ( Static members )● اعضای استاتیک (static members) نه تنها در کلاس های استاتیک (static class) قابل استفاده هستنند بلکه در کلاس های غیر استاتیک (none static class) نیز می توانند تعریف شوند.● متد های استاتیک (static methods) و خصوصیات استاتیک (static properties) نمی توانند دربدنه خود به فیلدهای غیراستاتیک (none static fields) و یا رخدادهای غیراستاتیک (none static events) و یا شی (object) تعریف شده در بدنه کلاس دسترسی داشته باشند مگر اینکه به صورت پارامتر به ان ها ارسال شوند.● اعضای غیر استاتیک (none static members) می توانند دربدنه خود به اعضای استاتیک (static members)  دسترسی داشته باشند .تفاوت اعضای استاتیک و غیراستاتیک● اعضای استاتیک (static members) بین تمامی شی های یک کلاس مشترک هستند و مقدار ان ها در بین تمامی شی های یک کلاس مشترک است. به عبارت دیگر متعلق به کلاس هستند .● اعضای غیر استاتیک متعلق به شی های ایجاد شده هستند نه کلاس.فیلدهای استاتیک :نکته :دو تا از موارد استفاده از فیلد های استاتیک :• در نگه داشتن  تعداد شی های ایجاد شده از یک نوع داده کلاس درسی شارپ• نگه داشتن مقادیر مشترک بین تمام نمونه های ایجاد شده از یک نوع داده کلاس درسی شارپمتد های استاتیک :نکته● در کلاس استاتیک میتوانیم متود overloading داشته باشیم و تو کلاس عادی هم میتونیم کلاس استاتیک overloading داشته باشیم .● متد های استاتیک (static methods) می توانندoverload شوند اما نمی توانند override شوند. زیرا انها متعلق به کلاس هستند و نه یک شی. ( در رابطه با overloading و overriding در مقالات بعدی بحث خواهد شد. )● سی شارپ از متغیرهای استاتیک (static variables) که به صورت محلی در بدنه متدهای استاتیک (static methods) و غیراستانیک (none static methods) ، تعریف می شوند حمایت نمی کند و ایجاد خطای زمان کامپایل می کند.● از نظر سرعت اجرا بین دو تا متد استاتیک (static method) و غیراستاتیک (none static) با بدنه یکسان ، متد استاتیک (static method) یک مقدار سریع تر اجرا می شود. زیرا در فراخوانی متد غیراستاتیک ، باید غیر نال بودن شی (object) نیز چک شود که زمان بیشتری را به اجرا تحمیل می کند. هرچند اختلاف زمانی در بیشتر موارد بسیار ناچیز استنکته‌ی مهمی که در اینجا وجود دارد این است که متدهای استاتیک تنها قادر به استفاده از متغیرهای استاتیک تعریف شده در سطح کلاس هستند.دوستان عزیز ، خیلی ممنون که وقت گران قدرتونو گذاشتید و تا به اینجا همراهیم کردید .اگه اشتباه مفهومی داشتم یا ایراد تایپی داشتم یا ایراد توضیح داشتم خیلی خوشحال میشم بهم بگید تا اصلاح کنم .مخلصیم ...</description>
                <category>Farhad Nosrati فرهاد نصرتی</category>
                <author>Farhad Nosrati فرهاد نصرتی</author>
                <pubDate>Tue, 15 Feb 2022 21:47:24 +0330</pubDate>
            </item>
                    <item>
                <title>Interface segregation Principle و dependency Inversion Principle</title>
                <link>https://virgool.io/@farhadnosrati/interface-segregation-principle-vs-dependency-inversion-principle-jeev9w5ct4xt</link>
                <description> دوتا اصل اخر solid که تلاش برای استفاده درست از Interface  ها دارد .Interface قابلیت های یکسان و پیاده سازی های متفاوت .هدف : اعمال قوانین و رفتار ( behavior ) به نرم افزار ‌که پیشنهاد شده برای تمام ،  ( اصطلاحا module هامون ) قوانین داشته باشیم . Interface segregation Principle چهارمین اصل solid : اصل جداسازی Interface ها .در این اصل تاکید میشود که کلاس ها نباید متد هایی که نیاز ندارن را پیاده سازی کنند ( اصطلاحا ، چرا باید متد هایی را در اختیار کاربر ( developer ) قرار دهیم که هیچوقت قرار نیست برایشان کد تولید شود و فقط NotImplimentedException ، throw میکند ) مثال : فرض کنید یه روال کار ( workflow ) داریم ، که سه مرحله دارد .زمان پیاده سازی : تمام این سه مرحله را در یک interface قرار دهیم ( اصطلاحا : سه signature در یک interface ) و به اعضای هر مرحله ، در سه کلاس جدا پیاده سازی کنیم ‌( یعنی یک پدر و ۳ فرزند یا inheritance ) . یادآوری : وقتی یک کلاس از Interface ارث بری میکن موظف است تمام signature های آن را پیاده سازی کند )‌پس این عمل موجب میشود در هر پیاده سازی فقط یکی از مراحل ( method ها ) رفتار یا بدنه مربوط به آن مرحله را داشته باشه و دوتا متد دیگه  NotImplimentedException پرتاپ کنند چون عملکرد انها مربوط به آن کلاس نیست .حالا فرض کنید ، اگر بعد ها یک مرحله دیگر به مراحلمان اضافه شود، چیکار باید بکنیم ؟؟؟ :)در این شرایط دو تا اصل solid را ( srp ، isp ) رعایت نمیکنیم .نتیجه : به همان اندازه که کاربرمان ( developer ) نیاز دارد ، متد در اختیارش قرار میدهیم ، نه بیشتر . Dependency Injection pattern یکی از راه های پیاده سازی اصل پنجم solid یعنی dependency Inversion Principle  (معکوس سازی وابستگی ها ) استفاده از Dependency Injection pattern هست که ، از اصل delegation استفاده میکند .معکوس سازی وابستگی ها یعنی ماژول های سطح بالا ( high-level module ) ، نباید به ماژول های سطح پایین ( low-level module ) وابسته باشند و یا از آنها خبر داشته باشند ( اصطلاحا،  لایه services نباید به لایه DAL وابسته باشه ). : Delegation یا DIهردو یک وظیفه دارند : وابستگی ها از کلاس ها خارج میکنند و به جای این که کلاس هایمان به پیاده سازی ( concrete ) وابسته شوند ، انهارا به یک سری قرار داد ( contract ) وابسته میکنند . تعریف delegation : تصور کنید ، یک سرویس داریم که یک سری وظایف دارد ، برای انجام وظایفش نیاز به یک سری اشیاع بیرون دارد ( مثل class ) که اگر خود سرویس ، مسئولیت تهیه این وابستگیها را داشته باشد ، کاملا به انها وابسته میشود ( مثل نمونه سازی از کلاس اشیا داخل سرویس ) .برای این که وابستگی ایجاد نشود ، میتوان مسئولیت ساخت نیازمندیها را به کلاس سرویس گیرنده ( استفاده کننده از سرویس ) داد و برایش قانون وضع کرد که اگر کسی خواست از کلاس سرویس دهنده استفاده کند ، باید خودش مسئولیت ساخت نیازمندیهایش را زمان نمونه سازی از سرویس‌دهنده ، برایش براورده کند .با این روش ما تمام وابستگی ها را از داخل سرویس دهنده خارج یا حذف میکنیم و مسئولیت آن را به سرویس گیرنده میدهیم ولی این روش مشکل ساز و سخت است . چطور از اصل DI یا delegation به درستی استفاده کنیم و مسئولیت تهیه نیازمندی هارا از سرویس گیرنده ، بگیریم و آن را به یک کلاس خارجی دیگر وابسته کنیم ( ارجاع بدیم جای دیگر ) . : DIContinerیه نوع service provider هست ( با رعایت اصل Delegation ) .تعریف : همه وابستگی ها را یکجا ( در یک subsystem ) تعريف میکنیم و همان subsystem مسئول مديريت همه وابستگی های نرم افزار ماست .برایش قانون وضع میکنیم  :مثال قانون : هر کی از سرویس Isms خواست استفاده کند ، کلاس sms را بهش پاس بده و بعد ها اگر business سرویس sms مان تغییر کند ، فقط کافی اسم کلاس sms فعلی را به اسم کلاس جدید مثل NewSMS تغییر دهیم .بدون این که به کد هایمان دست بخورد ، رفتار جدید را جایگزین رفتار قبلی کردیم .هدف :جداسازی از وابستگی .منعطف بودن نرم افزار یعنی قسمتی از نرم افزار رو تغییر بدیم بدون این که به جای دیگر نرمافزار دست بخوره .قابلیت تست بالا .اگه ایراد تایپی داشتم یا ایراد توضیح داشتم خیلی خوشحال میشم بهم بگید تا اصلاح کنم .</description>
                <category>Farhad Nosrati فرهاد نصرتی</category>
                <author>Farhad Nosrati فرهاد نصرتی</author>
                <pubDate>Tue, 23 Nov 2021 18:05:11 +0330</pubDate>
            </item>
                    <item>
                <title>انواع تست DotNet Core</title>
                <link>https://virgool.io/@farhadnosrati/%D8%A7%D9%86%D9%88%D8%A7%D8%B9-%D8%AA%D8%B3%D8%AA-dotnet-core-qdxk7bngjmlx</link>
                <description>انواع تست .1.  Ui Test . 2. Subcutaneous Testنوعی high-level Test هست که برای تست اولین لایه بعد از ui از این تست استفاده میشه . تو این نوع تست api به بعد و خود api هارو تست میکنیم و تمام نیاز مندی هاشونو مثل ارسال  data های ورودی ، تمام Dependency injaction هارو براشون میسازیم و ارسال می کنیم ، برای مثال اگر به دیتابیس connect میشه و persistent data انجام میده ، تو تستمون هم باید به طور واقعی باید data ذخیره کنیم .تقریبا میشه گفت یه شبیه‌سازی کامل میشه .3. Integration Testبرای تست لایه logic از این تست استفاده میکنم .توجه کنید طبق گفته خودشون : لایه logic و لایه infrastructure  به هم و هیچ تکنولوژی نباید وابسته باشه . ما فرض میکنیم لایه infrastructure به ORM وابسته هست و کنارش با سرویس ها هم کار میکنه .اگر تست ما با ساخت وابستگی ها و ارسالشون به هدفمون باشه ، نوع تستمون میشه Integration Test ولی اگه بدون ساخت وابستگیهاش باشه ، میشه Unit .برای ساخت وابستگیها میشه از Moq استفاده کرد .تست ها ۳ فاز دارن که اصطلاحا بهشون AAA هم میگن .1. A : arrangeقراره یه لاجیک تست کنیم ، نیازه که ما نیازمندی های هدفمون رو شبیه‌سازی کنیم ، یعنی : نمونه سازی کنیم یا یه سری متغیر تاریف کنیم تا بتونیم تست کنیم . 2. A : act متدی که باید تست بشرو ، تست میکنیم ( call میکنیمش ).3. A : assert نتیجه یا خروجی تست .#infrastructure #ui #data #unittesting #moq #xunit #ddd</description>
                <category>Farhad Nosrati فرهاد نصرتی</category>
                <author>Farhad Nosrati فرهاد نصرتی</author>
                <pubDate>Sat, 20 Nov 2021 23:47:11 +0330</pubDate>
            </item>
            </channel>
</rss>