<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Paula Fahmy</title>
    <description>The latest articles on Forem by Paula Fahmy (@paulafahmy).</description>
    <link>https://forem.com/paulafahmy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F632507%2F48a21a9b-59bf-4e10-9a73-58d3e84c90a9.jpeg</url>
      <title>Forem: Paula Fahmy</title>
      <link>https://forem.com/paulafahmy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/paulafahmy"/>
    <language>en</language>
    <item>
      <title>EF Core Change Tracking: The Bug Factory You Accidentally Built</title>
      <dc:creator>Paula Fahmy</dc:creator>
      <pubDate>Mon, 19 Jan 2026 13:25:38 +0000</pubDate>
      <link>https://forem.com/paulafahmy/ef-core-change-tracking-the-bug-factory-you-accidentally-built-3e2o</link>
      <guid>https://forem.com/paulafahmy/ef-core-change-tracking-the-bug-factory-you-accidentally-built-3e2o</guid>
      <description>&lt;p&gt;Most production EF Core problems do not start with broken code.&lt;br&gt;
They start with code that works.&lt;/p&gt;

&lt;p&gt;Queries return data. Updates succeed. Performance looks acceptable. Then traffic grows, memory spikes, SQL logs explode, or worse, random primary key violations start appearing in places no one touched. Someone flips &lt;code&gt;AsNoTracking()&lt;/code&gt; on or off, the system stabilizes, and the team moves on.&lt;/p&gt;

&lt;p&gt;Until it happens again &lt;em&gt;(somewhere else)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This article is about how we got there, why those bugs happen, and how to design your data access so you stop toggling tracking like a panic button.&lt;/p&gt;


&lt;h2&gt;
  
  
  How the Story Usually Starts
&lt;/h2&gt;

&lt;p&gt;EF Core &lt;strong&gt;enables&lt;/strong&gt; change tracking &lt;strong&gt;by default&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That sounds reasonable. You query entities, you modify them, you call &lt;code&gt;SaveChanges()&lt;/code&gt;. EF figures out what changed and generates SQL. Simple.&lt;/p&gt;

&lt;p&gt;That default quietly works its way into production.&lt;/p&gt;

&lt;p&gt;Every query tracks entities. Long-lived DbContexts accumulate them. Memory usage grows. GC pressure increases. Latency creeps up. Someone profiles the app and notices thousands of tracked entities sitting in memory doing nothing.&lt;/p&gt;

&lt;p&gt;The fix seems obvious.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AppDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseSqlServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Applies everywhere&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseQueryTrackingBehavior&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QueryTrackingBehavior&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoTracking&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Performance improves immediately. Memory drops. Everyone relaxes.&lt;/p&gt;

&lt;p&gt;Then the first relationship update fails with a duplicate key exception.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bug You Have Seen and Ignored
&lt;/h2&gt;

&lt;p&gt;Before the change, this worked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;existingCustomer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After disabling tracking globally, the same code throws:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cannot insert duplicate key row in object 'Customers'
The duplicate key value is (...)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing in the code changed. The database did not change. Only tracking did.&lt;/p&gt;

&lt;p&gt;This is not an EF Core bug. This is EF Core doing exactly what you asked, just not what you expected.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Change Tracking Actually Is
&lt;/h2&gt;

&lt;p&gt;Change tracking is EF Core keeping an internal graph of entities it is responsible for.&lt;/p&gt;

&lt;p&gt;Tracked entities have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A known identity (primary key)&lt;/li&gt;
&lt;li&gt;A known state (Unchanged, Modified, Added, Deleted)&lt;/li&gt;
&lt;li&gt;Snapshot or proxy-based detection of changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you call &lt;code&gt;SaveChanges()&lt;/code&gt;, EF:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compares tracked entities against their original state&lt;/li&gt;
&lt;li&gt;Generates SQL only for what changed&lt;/li&gt;
&lt;li&gt;Maintains relationship consistency automatically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When an entity is &lt;strong&gt;not tracked&lt;/strong&gt;, EF does none of this.&lt;/p&gt;

&lt;p&gt;No state. No identity map. No relationship awareness.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why AsNoTracking() Exists
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;AsNoTracking()&lt;/code&gt; tells EF:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This data is read-only. Do not waste memory or CPU tracking it."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is correct and valuable for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large result sets&lt;/li&gt;
&lt;li&gt;Read-heavy endpoints&lt;/li&gt;
&lt;li&gt;Reporting&lt;/li&gt;
&lt;li&gt;Projections that will never be saved&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsNoTracking&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is faster, leaner, and safer than tracking by default. Nothing is kept in memory for later usage (like when using tracking).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The mistake is using it everywhere without understanding the consequences&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Commands and Queries Are Not the Same Thing
&lt;/h2&gt;

&lt;p&gt;Queries want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Speed&lt;/li&gt;
&lt;li&gt;Low memory usage&lt;/li&gt;
&lt;li&gt;No side effects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Commands want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;State awareness&lt;/li&gt;
&lt;li&gt;Relationship handling&lt;/li&gt;
&lt;li&gt;Correct updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the same tracking strategy for both is where most systems break.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why SaveChanges() Does Nothing on Detached Entities
&lt;/h2&gt;

&lt;p&gt;Consider this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsNoTracking&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"New Name"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No error. No update. Nothing happens.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because EF is not tracking &lt;code&gt;user&lt;/code&gt;. From EF’s perspective, nothing changed &lt;strong&gt;because nothing was being watched&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is a silent failure. The worst kind.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Relationship Trap That Causes Duplicate Keys
&lt;/h2&gt;

&lt;p&gt;This one is more dangerous.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsNoTracking&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;existingCustomer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;EF sees:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An untracked &lt;code&gt;Order&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A referenced &lt;code&gt;Customer&lt;/code&gt; object&lt;/li&gt;
&lt;li&gt;No tracking information for either&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;So it assumes both are new.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;EF generates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;INSERT for Order&lt;/li&gt;
&lt;li&gt;INSERT for Customer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the customer already exists, the database rejects it.&lt;/p&gt;

&lt;p&gt;This is why disabling tracking globally often "fixes performance" and then breaks relationships.&lt;/p&gt;




&lt;h2&gt;
  
  
  Attach vs Update vs Already Tracked
&lt;/h2&gt;

&lt;p&gt;These three are not interchangeable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tracked Entity (Best Case)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Generated SQL:&lt;/span&gt;
&lt;span class="c1"&gt;// UPDATE [Products] SET [Price] = @p0 WHERE [Id] = @p1;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;EF tracks changes&lt;/li&gt;
&lt;li&gt;Only modified columns are updated&lt;/li&gt;
&lt;li&gt;Minimal SQL&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Attach
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsNoTracking&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;FirstAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Attach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Generated SQL: // UPDATE [Products] SET [Price] = @p0 WHERE [Id] = @p1;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;EF assumes entity exists&lt;/li&gt;
&lt;li&gt;Only modified properties are updated&lt;/li&gt;
&lt;li&gt;Safe when you know the entity is not new&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Update
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsNoTracking&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;FirstAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// This forces all columns to be updated&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;EF marks &lt;strong&gt;all properties&lt;/strong&gt; as modified&lt;/li&gt;
&lt;li&gt;Generates full-row UPDATE&lt;/li&gt;
&lt;li&gt;Large SQL statements&lt;/li&gt;
&lt;li&gt;Overwrites columns you did not touch
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Products&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;p0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Stock&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;p3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CategoryId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;p4&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;p5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling &lt;code&gt;Update()&lt;/code&gt; on an already tracked entity is unnecessary and wasteful. EF already knows what changed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical Demo Scenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Tracked Update Works
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"new@email.com"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Correct update. Minimal SQL.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. AsNoTracking Causes Silent No-Op
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsNoTracking&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"new@email.com"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No update. No error. No warning.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. AsNoTracking + Add Causes Duplicate Key Failure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Roles&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsNoTracking&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;roleId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Roles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;EF tries to insert an existing role.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Attach Updates Only Modified Columns
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Attach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsActive&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean and safe when used intentionally.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Update Forces Full-Row Update
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All columns marked modified. Bigger SQL. Higher risk.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Fix: Stop Toggling Tracking
&lt;/h2&gt;

&lt;p&gt;The root problem was not EF Core.&lt;br&gt;
It was mixing read and write intent in the same data access path.&lt;/p&gt;

&lt;p&gt;The fix was structural.&lt;/p&gt;


&lt;h2&gt;
  
  
  Splitting Repositories by Intent
&lt;/h2&gt;

&lt;p&gt;Instead of enabling and disabling tracking everywhere, we split repositories.&lt;/p&gt;
&lt;h3&gt;
  
  
  Read-Only Repository
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderReadRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OrderDto&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsNoTracking&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;OrderDto&lt;/span&gt;&lt;span class="p"&gt;(...))&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Always no tracking&lt;/li&gt;
&lt;li&gt;Safe by design&lt;/li&gt;
&lt;li&gt;Easy to cache&lt;/li&gt;
&lt;li&gt;Easy to move to a read replica later&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Read-Write Repository
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderWriteRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetTracked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Tracking is expected&lt;/li&gt;
&lt;li&gt;Relationships work&lt;/li&gt;
&lt;li&gt;Updates are correct&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No flags. No guessing.&lt;/p&gt;

&lt;p&gt;One more good idea is to have this kind of configuration set once and for all:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReadOnlyRepository&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;TEntity&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;
&lt;span class="err"&gt;{&lt;/span&gt;

&lt;span class="nc"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;DbContext&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;DbSet&lt;/span&gt; &lt;span class="n"&gt;_dbSet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nf"&gt;ReadOnlyRepository&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DbContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;_dbSet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TEntity&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ChangeTracker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QueryTrackingBehavior&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QueryTrackingBehavior&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoTracking&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;IQueryable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TEntity&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_dbSet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TEntity&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetByIdAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_dbSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;AsTask&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReadWriteRepository&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;TEntity&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;
&lt;span class="err"&gt;{&lt;/span&gt;

&lt;span class="nc"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;DbContext&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;DbSet&lt;/span&gt; &lt;span class="n"&gt;_dbSet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nf"&gt;ReadWriteRepository&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DbContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;_dbSet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TEntity&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ChangeTracker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QueryTrackingBehavior&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QueryTrackingBehavior&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TrackAll&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;IQueryable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TEntity&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_dbSet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TEntity&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetByIdAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_dbSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;AsTask&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TEntity&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_dbSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TEntity&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_dbSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TEntity&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_dbSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why This Is Not Just Clean Code Overhead
&lt;/h2&gt;

&lt;p&gt;This approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eliminates accidental tracking&lt;/li&gt;
&lt;li&gt;Prevents silent no-ops&lt;/li&gt;
&lt;li&gt;Prevents duplicate key bugs&lt;/li&gt;
&lt;li&gt;Makes performance predictable&lt;/li&gt;
&lt;li&gt;Makes intent explicit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the application layer, it aligns naturally.&lt;/p&gt;

&lt;p&gt;A GET endpoint injects a read-only repository.&lt;br&gt;
A command handler injects a write repository.&lt;/p&gt;

&lt;p&gt;This pattern scales upward.&lt;br&gt;
It enables read replicas, caching layers, and even separate databases later.&lt;/p&gt;

&lt;p&gt;Not because you planned CQRS.&lt;br&gt;
Because you respected intent.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tracking is powerful but expensive&lt;/li&gt;
&lt;li&gt;NoTracking is safe only for reads&lt;/li&gt;
&lt;li&gt;SaveChanges does nothing for detached entities&lt;/li&gt;
&lt;li&gt;Update is a blunt instrument&lt;/li&gt;
&lt;li&gt;Attach is precise when used correctly&lt;/li&gt;
&lt;li&gt;Repository design must reflect query vs command intent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You do not need full CQRS to think this way.&lt;br&gt;
You just need to stop pretending reads and writes are the same thing.&lt;/p&gt;

&lt;p&gt;EF Core was never the problem.&lt;br&gt;
The defaults were.&lt;/p&gt;

&lt;p&gt;Once you understand that, the bugs you ignored for years suddenly make sense.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Understanding the Magic of Logarithms in Binary Search</title>
      <dc:creator>Paula Fahmy</dc:creator>
      <pubDate>Sat, 09 Mar 2024 15:17:46 +0000</pubDate>
      <link>https://forem.com/paulafahmy/understanding-the-magic-of-logarithms-in-binary-search-2pff</link>
      <guid>https://forem.com/paulafahmy/understanding-the-magic-of-logarithms-in-binary-search-2pff</guid>
      <description>&lt;p&gt;Hey community! 👋 Today, let's demystify the magic behind the efficiency of algorithms &lt;strong&gt;like binary search&lt;/strong&gt;. Ever wondered why we say binary search has a time complexity of &lt;strong&gt;O(log N)&lt;/strong&gt;? &lt;/p&gt;

&lt;p&gt;Let's break it down in simple terms.&lt;/p&gt;

&lt;p&gt;Imagine you have a row of boxes, and you want to find a particular item in one of them. Now, let's use binary search to make this process super efficient.&lt;/p&gt;

&lt;p&gt;Step 1: Start with 16 boxes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📦📦📦📦📦📦📦📦📦📦📦📦📦📦📦📦
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Each time, divide the number of remaining boxes by 2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📦📦📦📦📦📦📦📦   📦📦📦📦📦📦📦📦
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3: Repeat until you have only one box left.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        📦📦📦📦📦📦📦📦   📦📦📦📦📦📦📦📦
Step 1:           📦📦📦📦   📦📦📦📦
Step 2:                📦📦   📦📦
Step 3:                   📦   📦
Step 4:                      📦
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the cool part: The number of steps it takes to go from 16 boxes to 1 box is surprisingly related to the concept of logarithms!&lt;/p&gt;

&lt;p&gt;Mathematically, we can represent this as:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.sciweavers.org%2Ftex2img.php%3Feq%3DN%2520%252A%2520%25280.5%2529%255E%257Bsteps%257D%2520%253D%25201%26bc%3DWhite%26fc%3DBlack%26im%3Djpg%26fs%3D12%26ff%3Darev%26edit%3D0" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.sciweavers.org%2Ftex2img.php%3Feq%3DN%2520%252A%2520%25280.5%2529%255E%257Bsteps%257D%2520%253D%25201%26bc%3DWhite%26fc%3DBlack%26im%3Djpg%26fs%3D12%26ff%3Darev%26edit%3D0" alt="img" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the case of our 16 boxes example, it becomes:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.sciweavers.org%2Ftex2img.php%3Feq%3D16%2520%252A%2520%25280.5%2529%255E%257Bsteps%257D%2520%253D%25201%26bc%3DWhite%26fc%3DBlack%26im%3Djpg%26fs%3D12%26ff%3Darev%26edit%3D0" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.sciweavers.org%2Ftex2img.php%3Feq%3D16%2520%252A%2520%25280.5%2529%255E%257Bsteps%257D%2520%253D%25201%26bc%3DWhite%26fc%3DBlack%26im%3Djpg%26fs%3D12%26ff%3Darev%26edit%3D0" alt="img" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's use logarithms to solve for the number of steps. Taking the base-2 logarithm of both sides gives us:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.sciweavers.org%2Ftex2img.php%3Feq%3DLog_%257B2%257DN%2520%253D%2520steps%26bc%3DWhite%26fc%3DBlack%26im%3Djpg%26fs%3D12%26ff%3Darev%26edit%3D0" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.sciweavers.org%2Ftex2img.php%3Feq%3DLog_%257B2%257DN%2520%253D%2520steps%26bc%3DWhite%26fc%3DBlack%26im%3Djpg%26fs%3D12%26ff%3Darev%26edit%3D0" alt="img" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, in this example:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.sciweavers.org%2Ftex2img.php%3Feq%3DLog_%257B2%257D16%2520%253D%2520steps%26bc%3DWhite%26fc%3DBlack%26im%3Djpg%26fs%3D12%26ff%3Darev%26edit%3D0" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.sciweavers.org%2Ftex2img.php%3Feq%3DLog_%257B2%257D16%2520%253D%2520steps%26bc%3DWhite%26fc%3DBlack%26im%3Djpg%26fs%3D12%26ff%3Darev%26edit%3D0" alt="img" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Steps in this case equals to &lt;strong&gt;4&lt;/strong&gt;..&lt;/p&gt;

&lt;p&gt;Voila! The number of steps it takes to find an item in our binary search is logarithmic with respect to the number of elements (N) we started with. Hence, the time complexity of binary search is O(log N).&lt;/p&gt;

&lt;p&gt;Understanding this concept can help us appreciate the efficiency of algorithms that reduce the search space by half in each step. &lt;/p&gt;

&lt;p&gt;Happy searching! 🔍💡 #AlgorithmMagic #BinarySearch #LogarithmsExplained&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Interview Questions: Singleton Pattern vs the Static Keyword</title>
      <dc:creator>Paula Fahmy</dc:creator>
      <pubDate>Fri, 04 Mar 2022 14:46:11 +0000</pubDate>
      <link>https://forem.com/paulafahmy/the-singleton-design-pattern-vs-when-to-use-the-static-keyword-1e14</link>
      <guid>https://forem.com/paulafahmy/the-singleton-design-pattern-vs-when-to-use-the-static-keyword-1e14</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you've been in the tech industry for a while, you've certainly heard about the buzz words: "Design Patterns", maybe you've also heard about a famous pattern, the &lt;strong&gt;Singleton&lt;/strong&gt;. Additionally, if you've been coding for a brief period, I'm hundred percent sure you've used the keyword &lt;strong&gt;&lt;code&gt;static&lt;/code&gt;&lt;/strong&gt; in one or more of your favorite programming languages.&lt;/p&gt;

&lt;p&gt;For all of you experienced techies, you might already recognize that &lt;strong&gt;"Singletons"&lt;/strong&gt; are used to create &lt;strong&gt;one and only one&lt;/strong&gt; instance object of a class.&lt;/p&gt;

&lt;p&gt;Hello World! once again, today with another interesting programming topic, let's discuss the differences between using the keyword &lt;strong&gt;&lt;code&gt;static&lt;/code&gt;&lt;/strong&gt; and implementing the &lt;strong&gt;Singleton Design Pattern&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Tech explanation aside, I want to quickly point out that I was hit by question lately while interviewing for a .NET Developer role in a software house, luckily I was prepared because it has popped into my mind a while ago before the interview itself.&lt;br&gt;
Anyways, &lt;strong&gt;this is an interview question&lt;/strong&gt;, so ladies and gentlemen, start taking notes.&lt;/p&gt;

&lt;p&gt;I'm going to host my discussion &lt;strong&gt;in C#&lt;/strong&gt; since it is a really powerful programming language, and it is in fact &lt;a href="https://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Java#:~:text=C%23%20and%20Java%20are%20similar,like%20C%20and%20C%2B%2B." rel="noopener noreferrer"&gt;similar to other famous languages like Java and C++&lt;/a&gt;, just keep in mind that what's written in this blog should apply &lt;strong&gt;to any OOP language&lt;/strong&gt;, so pick your favorite, and hop on. &lt;/p&gt;
&lt;h2&gt;
  
  
  The &lt;code&gt;static&lt;/code&gt; Keyword
&lt;/h2&gt;

&lt;p&gt;We normally use the static keyword &lt;em&gt;(in C#)&lt;/em&gt; in order to declare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static Classes&lt;/li&gt;
&lt;li&gt;Static Class Members, such as:

&lt;ul&gt;
&lt;li&gt; Constructors&lt;/li&gt;
&lt;li&gt; Fields&lt;/li&gt;
&lt;li&gt; Properties&lt;/li&gt;
&lt;li&gt; Methods&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This specific type of declaration is useful when only one copy of the object (class or class members) is needed that single instance is shared &lt;strong&gt;globally&lt;/strong&gt; among all other objects, &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/static" rel="noopener noreferrer"&gt;in other words&lt;/a&gt; the static variable &lt;strong&gt;belongs to the type itself&lt;/strong&gt; rather than to a specific object created from that type.&lt;/p&gt;

&lt;p&gt;Let me throw a real-life example to make things a little bit clearer.&lt;br&gt;
I love Mustangs, the Ford cars of course &lt;em&gt;(who doesn't!)&lt;/em&gt;...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftlkfosde4974s7fhoj0e.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftlkfosde4974s7fhoj0e.jpg" width="800" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's say we are developing a game, and we want to model this type of car on its own class, what are the properties that we should include?&lt;/p&gt;

&lt;p&gt;I'm thinking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Color&lt;/li&gt;
&lt;li&gt;Body type (hatchback or regular)&lt;/li&gt;
&lt;li&gt;Top Speed (could differ depending on the model)&lt;/li&gt;
&lt;li&gt;First year of production (1965)&lt;/li&gt;
&lt;li&gt;Year Model&lt;/li&gt;
&lt;li&gt;Logo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, we know that "First year of production" for this type of car will &lt;strong&gt;always&lt;/strong&gt; be 1965, also the "Logo", it's the same for all cars. Now let's say Ford decides to modify the logo for some reason, it should be changed for all cars, right?&lt;br&gt;
These two variables are perfect candidates for static variables.&lt;br&gt;
Other variables should depend on the car itself (the object) and could differ for every single one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Mustang&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;IsHatchback&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;TopSpeed&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;YearModel&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;FirstYearInProduction&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1965&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;LogoURL&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://ford.com/logo.png"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See how the compiler complains when trying to access the &lt;strong&gt;static variable&lt;/strong&gt; from an &lt;strong&gt;instance object&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbda4xtluadoi2ts4zdnm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbda4xtluadoi2ts4zdnm.png" width="800" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which makes sense actually, why would I ask about the first production year using my car, or my friend's car, &lt;strong&gt;it's all the same at the end&lt;/strong&gt;, right?&lt;/p&gt;

&lt;p&gt;So in a way, &lt;code&gt;FirstYearInProduction&lt;/code&gt; and &lt;code&gt;LogoURL&lt;/code&gt; are being singleton-like in their nature, same value for all instances, right?&lt;/p&gt;

&lt;p&gt;Like fields and properties, &lt;strong&gt;static methods&lt;/strong&gt; also belong to the type itself.&lt;br&gt;
.. and for the sake completeness of this article, let me list down the features of static classes in C#:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They can only contain static data members.&lt;/li&gt;
&lt;li&gt;It is not allowed to create objects of the static class.&lt;/li&gt;
&lt;li&gt;Static classes are sealed (could not be inherited from).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Okay, now that we've scratched the surface of the &lt;strong&gt;&lt;code&gt;static&lt;/code&gt; keyword&lt;/strong&gt; in most programming languages, now let's discuss what a &lt;strong&gt;Singleton Pattern&lt;/strong&gt; means in order to formulate a rational comparison. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But wait, what are design patterns in the first place⁉️&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Design Patterns
&lt;/h2&gt;

&lt;p&gt;According to &lt;a href="https://refactoring.guru/design-patterns" rel="noopener noreferrer"&gt;refactoring.guru&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Design patterns are typical solutions to common problems&lt;br&gt;
in software design. Each pattern is like a &lt;strong&gt;blueprint&lt;/strong&gt;&lt;br&gt;
that you can customize to solve a particular&lt;br&gt;
design problem in your code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Design Patterns comes in different sizes and shapes, and they can be categorized into 3 main types:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Creational:&lt;/strong&gt; These patterns are designed for class instantiation. They can be either class-creation patterns or object-creational patterns.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Structural&lt;/strong&gt;: These patterns are designed with regard to a class's structure and composition. The main goal of most of these patterns is to increase the functionality of the class(es) involved, without changing much of its composition.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Behavioral&lt;/strong&gt;: These patterns are designed depending on how one class communicates with others.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Singleton Design Pattern
&lt;/h2&gt;

&lt;p&gt;Now, let's get back to our main subject, the Singleton Pattern.&lt;/p&gt;

&lt;p&gt;Singletons are not part of a specific language (not a keyword for example) or do they belong to frameworks. Singletons are just special classes built in a special way to fit in a special use case.. &lt;br&gt;
&lt;em&gt;Lot of "specials", huh?&lt;/em&gt; That's the case with most modern design patterns.&lt;/p&gt;

&lt;p&gt;The pattern's main objective is to create only one instance of a class and to provide &lt;strong&gt;only one global access point&lt;/strong&gt; to that object.&lt;/p&gt;

&lt;p&gt;As you might've guessed, this description fits nicely into the &lt;strong&gt;Creational patterns&lt;/strong&gt; category, because at the end, we are &lt;strong&gt;"creating"&lt;/strong&gt; an object, with only a "&lt;strong&gt;single&lt;/strong&gt;" instance.&lt;/p&gt;

&lt;p&gt;So filling in the gaps of Refactoring Guru's definition stated above, the current design problem at hand is that &lt;strong&gt;we need to create only one instance of the object&lt;/strong&gt;, that's why we've chosen the Singleton Design Pattern.&lt;/p&gt;
&lt;h3&gt;
  
  
  Singleton Implementation in &lt;strong&gt;C#&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now I'm going to write down a couple of versions of Singletons in C#, let's start first by the simplest one, a &lt;strong&gt;Naïve&lt;/strong&gt; one if you will, and I'm going to explain why it wouldn't hold up in tough environments in a moment.&lt;/p&gt;
&lt;h4&gt;
  
  
  Naïve Singleton
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NaiveSingleton&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;NaiveSingleton&lt;/span&gt; &lt;span class="n"&gt;_instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;NaiveSingleton&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;NaiveSingleton&lt;/span&gt; &lt;span class="nf"&gt;GetInstance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_instance&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_instance&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NaiveSingleton&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;someBusinessLogic&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;First up, &lt;strong&gt;notice the &lt;code&gt;sealed&lt;/code&gt; keyword&lt;/strong&gt;, Singletons should always be a &lt;strong&gt;"sealed"&lt;/strong&gt; in order to prevent class inheritance, which could end up with multiple instances and this contrasts the whole point of Singletons.&lt;/p&gt;

&lt;p&gt;Also, the constructor must be private to prevent creating &lt;strong&gt;&lt;code&gt;new&lt;/code&gt;&lt;/strong&gt; instances.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now the &lt;code&gt;GetInstance()&lt;/code&gt; method&lt;/strong&gt;, this is the main entry point for the class, it serves as an alternative to the constructor &lt;em&gt;(which we hid using the *&lt;/em&gt;&lt;code&gt;private&lt;/code&gt;** keyword)* and lets clients access the same instance of this class over and over. &lt;br&gt;
On the first run, it creates a singleton object and assigns it into the static field &lt;strong&gt;&lt;code&gt;_instance&lt;/code&gt;&lt;/strong&gt;. &lt;br&gt;
On subsequent runs, it returns the existing object stored in the static field.&lt;/p&gt;

&lt;p&gt;To test our code, we could run this snippet on the &lt;code&gt;main()&lt;/code&gt; function of our console application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;NaiveSingleton&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NaiveSingleton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetInstance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;NaiveSingleton&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NaiveSingleton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetInstance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Singleton works, both variables contain the same instance."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Singleton failed, variables contain different instances."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the output should be as expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Singleton works, both variables contain the same instance.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, both &lt;code&gt;s1&lt;/code&gt; and &lt;code&gt;s2&lt;/code&gt; are essentially the same, right? Ummm, not always.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Of course, there's a culprit, it shouldn't be that straightforward huh? 😁&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Why isn't our solution sophisticated enough?
&lt;/h4&gt;

&lt;p&gt;To better explain my point, let me adjust our &lt;code&gt;main()&lt;/code&gt; function a little bit and introduce some asynchrony into the problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚠️ Disclaimer:&lt;/strong&gt; The following part is a little bit advanced &lt;em&gt;(just a little bit, I promise)&lt;/em&gt; and needs some basic understanding of the asynchronous operation in C#, if you don't feel comfortable with &lt;code&gt;async&lt;/code&gt;, &lt;code&gt;await&lt;/code&gt; and C# Tasks, feel free to check my &lt;strong&gt;&lt;a href="https://dev.to/paulafahmy/series/12755"&gt;DEV.TO series about the topic&lt;/a&gt;&lt;/strong&gt; where I attempt to make a simple cup of tea, &lt;strong&gt;asynchronously&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Back to our &lt;code&gt;main()&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Delay getting an instance of our singleton by doing so inside a task.&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;NaiveSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ts1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;NaiveSingleton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetInstance&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;NaiveSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ts2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;NaiveSingleton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetInstance&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="c1"&gt;// Run both tasks in parallel&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WhenAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ts1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ts2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Get the result of each task&lt;/span&gt;
    &lt;span class="n"&gt;NaiveSingleton&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ts1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;NaiveSingleton&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ts2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Singleton works, both variables contain the same instance."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Singleton failed, variables contain different instances."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main point of the previous modification is to access the &lt;code&gt;GetInstance()&lt;/code&gt; method of the Singleton from two different &lt;strong&gt;&lt;em&gt;"contexts"&lt;/em&gt;&lt;/strong&gt; at the same time, for example, two different threads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📝 Side Note:&lt;/strong&gt; The previous modification might have not essentially created a whole new thread, but it certainly accessed the &lt;code&gt;GetInstance()&lt;/code&gt; method from two different contexts, for an explanation, read through &lt;a href="https://stackoverflow.com/a/4130347/9312267" rel="noopener noreferrer"&gt;this StackOverflow answer&lt;/a&gt;, you can check &lt;a href="https://stackoverflow.com/a/4130204/9312267" rel="noopener noreferrer"&gt;this shorter one too&lt;/a&gt; on the same question.&lt;/p&gt;

&lt;p&gt;Now, let's check the output of the previous modification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Singleton failed, variables contain different instances.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;So, what happened?&lt;/strong&gt;&lt;br&gt;
Check the comments within the snippet for clarifications&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;NaiveSingleton&lt;/span&gt; &lt;span class="nf"&gt;GetInstance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Both contexts entered the GetInstance() method at the same time,&lt;/span&gt;
    &lt;span class="c1"&gt;// both of them queried whether _instance is null at the same time,&lt;/span&gt;
    &lt;span class="c1"&gt;// and since _instance was in fact initially null,&lt;/span&gt;
    &lt;span class="c1"&gt;// both succeeded to enter the if clause at the same time &lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_instance&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="c1"&gt;// .. which resulted in the creation of a new Instance &lt;/span&gt;
         &lt;span class="c1"&gt;// twice for each context&lt;/span&gt;
        &lt;span class="n"&gt;_instance&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NaiveSingleton&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's fix this small bug, and make our Singleton a little bit more Sophisticated.&lt;/p&gt;

&lt;h4&gt;
  
  
  Sophisticated Singleton
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SophisticatedSingleton&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;SophisticatedSingleton&lt;/span&gt; &lt;span class="n"&gt;_instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;_lock&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;SophisticatedSingleton&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;SophisticatedSingleton&lt;/span&gt; &lt;span class="nf"&gt;GetInstance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;lock&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_lock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_instance&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;_instance&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SophisticatedSingleton&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Straight up, we could notice a couple of lines making this version a little different than its Naïve sibling.&lt;/p&gt;

&lt;p&gt;Simply speaking, I've added a lock object and utilized it using C#'s &lt;strong&gt;&lt;code&gt;lock()&lt;/code&gt; keyword&lt;/strong&gt;, this will be used to &lt;strong&gt;synchronize threads&lt;/strong&gt; during first access to the Singleton.&lt;/p&gt;

&lt;p&gt;During the initial launch of the program, there are no instances yet, multiple contexts (caused by the &lt;code&gt;Task.WhenAll()&lt;/code&gt; call) will simultaneously reach the lock at the same time. &lt;br&gt;
The first of them will acquire it and will proceed further creating an instance, while the others will wait for the lock to be released.&lt;/p&gt;

&lt;p&gt;Once the first context leaves the lock block, another context that might have been waiting for the lock release will then enter this section.&lt;br&gt;
This time the Singleton field is already initialized and there would be no further need to initialize it once more with a new instance.&lt;/p&gt;

&lt;p&gt;Now let's test our fix, I'll replace references to the &lt;code&gt;NaiveSingleton&lt;/code&gt; in our &lt;code&gt;Main()&lt;/code&gt; method and migrate to the newer &lt;code&gt;SophisticatedSingleton&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Delay getting an instance of our singleton by doing so inside a task.&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SophisticatedSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ts1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;SophisticatedSingleton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetInstance&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SophisticatedSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ts2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;SophisticatedSingleton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetInstance&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="c1"&gt;// Run both tasks in parallel&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WhenAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ts1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ts2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Get the result of each task&lt;/span&gt;
    &lt;span class="n"&gt;SophisticatedSingleton&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ts1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;SophisticatedSingleton&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ts2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Singleton works, both variables contain the same instance."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Singleton failed, variables contain different instances."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here goes our expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Singleton works, both variables contain the same instance.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Hurray 🥳!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Eager vs Lazy Initialization
&lt;/h4&gt;

&lt;p&gt;There is yet one another customization to how you'd implement a singleton.&lt;/p&gt;

&lt;p&gt;We've been initializing Singletons throughout the previous couple of examples &lt;strong&gt;"lazily"&lt;/strong&gt;, which means that an instance would not be initialized unless the &lt;code&gt;getInstance()&lt;/code&gt; function has been called and the &lt;code&gt;_instance == null&lt;/code&gt; check returned true, only then would an instance be initialized, in other words, &lt;code&gt;_instance&lt;/code&gt; would never be initialized unless at least one context needs it.&lt;/p&gt;

&lt;p&gt;But what if we want the Singleton's instance to be available right away?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EagerSingleton&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;EagerSingleton&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;EagerSingleton&lt;/span&gt; &lt;span class="n"&gt;_instance&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;EagerSingleton&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;EagerSingleton&lt;/span&gt; &lt;span class="nf"&gt;GetInstance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A minor tweak to the original Naïve Singleton could be done, where we initialize the static &lt;code&gt;_instance&lt;/code&gt; field inline, making it ready for usage right before needing it.&lt;/p&gt;

&lt;p&gt;This has the benefit of making the instance &lt;strong&gt;&lt;em&gt;instantly&lt;/em&gt; available&lt;/strong&gt;, &lt;strong&gt;but&lt;/strong&gt;, a major drawback should be accounted for. &lt;/p&gt;

&lt;p&gt;Eagerly initializing the field means that it would be initialized even if no one ever needs it, taking into consideration whether the instance itself might require heavy processing or a substantially large amount of memory bytes, this would certainly form an overhead for your application, so be sure to use this technique wisely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Cases of Singletons
&lt;/h2&gt;

&lt;p&gt;Now I can think of a couple of real-life use cases, for example, we could design our own custom &lt;strong&gt;Logger&lt;/strong&gt; class by it being defined as a singleton. No need to create a new instance every time we need to log something into the console or the database.&lt;/p&gt;

&lt;p&gt;Speaking of databases, we could also build our database context using the Singleton Pattern, because again, no need for multiple instances, only one is enough.&lt;br&gt;
&lt;a href="https://stackoverflow.com/questions/228164/on-design-patterns-when-should-i-use-the-singleton#comment71466229_228168" rel="noopener noreferrer"&gt;One would argue&lt;/a&gt; that it would be better to register it as a service (depending on the dependency injection framework of your choice) and inject it to whatever the class that needs it, which is totally valid of course, but for simple projects, I think it would be perfectly fine to design the context as a Singleton.&lt;/p&gt;

&lt;p&gt;In addition to database connections and logging services, Singleton classes could also be used for driver objects, caching, or thread pools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway 📒
&lt;/h2&gt;

&lt;p&gt;So to answer the main question:&lt;/p&gt;

&lt;h3&gt;
  
  
  What are the similarities and differences between the two approaches?
&lt;/h3&gt;

&lt;p&gt;As you might've already noticed, a Singleton is nothing but some wrapping methods around a core static field packaged into a &lt;strong&gt;&lt;code&gt;sealed&lt;/code&gt;&lt;/strong&gt; class that has no public constructors.&lt;/p&gt;

&lt;p&gt;A static field indeed helps in making an object globally accessed, but by itself, it neither does help in making it &lt;strong&gt;threadsafe&lt;/strong&gt; nor &lt;strong&gt;lazily constructed&lt;/strong&gt;, it does not introduce &lt;strong&gt;encapsulation&lt;/strong&gt; into the game, meaning you'll access the field directly without a custom &lt;strong&gt;"getter"&lt;/strong&gt; &lt;em&gt;(like &lt;code&gt;getInstance()&lt;/code&gt; method in our case)&lt;/em&gt; and it might be dangerous to expose the field like so in some cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here are some key differences that could also be included in our research:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Singleton can &lt;strong&gt;implement interfaces&lt;/strong&gt; and &lt;strong&gt;inherit&lt;/strong&gt; from other classes. While a &lt;strong&gt;static class cannot&lt;/strong&gt; inherit their instance members. So Singleton is more flexible than static classes and can maintain state.&lt;/li&gt;
&lt;li&gt;A Singleton can be initialized lazily, while a static class is generally initialized when it is first loaded.&lt;/li&gt;
&lt;li&gt;Singleton Objects are stored on the &lt;strong&gt;heap&lt;/strong&gt; while static classes are stored in &lt;strong&gt;stack&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Singleton Objects can &lt;strong&gt;dispose&lt;/strong&gt; but static classes can't.&lt;/li&gt;
&lt;li&gt;Singleton Objects can &lt;strong&gt;clone&lt;/strong&gt; but static classes can't.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;To sum up 📒&lt;/strong&gt;, I could use this answer from &lt;a href="https://stackoverflow.com/a/4566209/9312267" rel="noopener noreferrer"&gt;Stackoverflow&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Static classes are not for anything that needs state. It is useful for putting a bunch of functions together i.e Math (or Utils in projects). So the class name just gives us a clue where we can find the functions and nothing more.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So whenever you need to choose between the two approaches, ask yourself the following question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If there is a bunch of functions that should be packaged together&lt;/strong&gt;: go for static.&lt;br&gt;
Anything else which needs &lt;strong&gt;single access to some resources and state maintaining&lt;/strong&gt;, singleton should be the way to go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side Note 🗒️:&lt;/strong&gt;&lt;br&gt;
Singletons are sometimes considered as &lt;strong&gt;anti-patterns&lt;/strong&gt;, here's why:&lt;/p&gt;

&lt;p&gt;As we've discussed, Singletons are basically a way to use global variables, global variables are bad because any code anywhere in the system can change their values. So when debugging, it can be challenging to figure out which code path leads to the Singleton's current state.&lt;br&gt;
The previous problem can be handled by proper encapsulation mechanisms though, just be a little bit mindful about how you implement them.&lt;/p&gt;

&lt;p&gt;I'd recommend reading this &lt;a href="https://stackoverflow.com/questions/12755539/why-is-singleton-considered-an-anti-pattern" rel="noopener noreferrer"&gt;StackOverflow&lt;/a&gt; thread about the topic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outro
&lt;/h2&gt;

&lt;p&gt;A Singleton class is a pattern, one of many in fact. It would be a great idea to read more about other design patterns too, &lt;a href="https://refactoring.guru/design-patterns" rel="noopener noreferrer"&gt;Refactoring Guru&lt;/a&gt; hosts explanations to most of them in a nicely illustrated way, be sure to check them out.&lt;/p&gt;

&lt;p&gt;It was my pleasure to conduct this research, and I hope you'd find it interesting and informative. In case you have something on your mind, let's discuss it in the comments section.&lt;/p&gt;

&lt;p&gt;Keep Coding 💻!&lt;br&gt;
See you soon. 👋&lt;/p&gt;

</description>
      <category>design</category>
      <category>software</category>
      <category>architecture</category>
      <category>interview</category>
    </item>
    <item>
      <title>One-Tap Deployments with Nginx and Docker: Serving your Web Cluster w/ Compose 🐳</title>
      <dc:creator>Paula Fahmy</dc:creator>
      <pubDate>Fri, 20 Aug 2021 19:46:30 +0000</pubDate>
      <link>https://forem.com/paulafahmy/one-tap-deployments-with-nginx-and-docker-serving-your-web-cluster-w-compose-29f6</link>
      <guid>https://forem.com/paulafahmy/one-tap-deployments-with-nginx-and-docker-serving-your-web-cluster-w-compose-29f6</guid>
      <description>&lt;p&gt;Welcome back to the series. In the &lt;a href="https://dev.to/paulafahmy/one-tap-deployments-with-nginx-and-docker-configuring-for-load-balancing-56b"&gt;last article&lt;/a&gt; we discussed multiple approaches to configure Nginx for web applications and clusters, now that we've got ourselves good knowledge about it, let's see how we can take it one step further by containerizing a configured Nginx instance pointing at our cluster of backend containers, and deploying the full setup with one tap.&lt;/p&gt;

&lt;p&gt;Let's start with the &lt;strong&gt;Docker Compose&lt;/strong&gt; file, I'll be using the published &lt;strong&gt;&lt;code&gt;strm/helloworld-http&lt;/code&gt;&lt;/strong&gt; image as the web application for our project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

  &lt;span class="na"&gt;app1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;strm/helloworld-http&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hello_1&lt;/span&gt;

  &lt;span class="na"&gt;app2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;strm/helloworld-http&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hello_2&lt;/span&gt;

  &lt;span class="na"&gt;app3&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;strm/helloworld-http&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hello_3&lt;/span&gt;

  &lt;span class="na"&gt;nginxserver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./Server&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:8080"&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;server&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the file above, I created 3 containers from the Image &lt;code&gt;strm/helloworld-http&lt;/code&gt;, I also gave each one a friendly name so that we can access it easily from Nginx using Docker's own DNS lookup.&lt;br&gt;
I also added the server container, pointing to its own Dockerfile location and having a name too.&lt;/p&gt;

&lt;p&gt;Now, onto &lt;strong&gt;Nginx's Dockerfile&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; nginx&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; nginx.conf /etc/nginx/nginx.conf&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The whole point of the file is to copy the configuration automatically into the container upon building it&lt;/strong&gt;, &lt;code&gt;/etc/nginx&lt;/code&gt; is the path where Nginx reads its configurations which would be copied from the local machine.&lt;/p&gt;

&lt;p&gt;Finally, let's see how to &lt;code&gt;.conf&lt;/code&gt; file would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kn"&gt;upstream&lt;/span&gt; &lt;span class="s"&gt;apps&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="s"&gt;hello_1:80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="s"&gt;hello_2:80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="s"&gt;hello_3:80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://apps/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;events&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important Docker 🐳 Notes:&lt;/strong&gt;&lt;br&gt;
We used the &lt;strong&gt;container names&lt;/strong&gt; we set earlier in the &lt;strong&gt;compose file&lt;/strong&gt; to access the upstream servers, this is valid because Docker creates a DNS record automatically to point to the container's IP address using its name, that way, you don't have to keep track of the container's IP address.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Container Name&lt;/th&gt;
&lt;th&gt;IP Address&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;hello_1&lt;/td&gt;
&lt;td&gt;172.24.0.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hello_2&lt;/td&gt;
&lt;td&gt;172.24.0.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hello_3&lt;/td&gt;
&lt;td&gt;172.24.0.6&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Another note to take is that we &lt;strong&gt;did not do any port mapping&lt;/strong&gt; for our three apps, I skipped it for a purpose, here is why:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📝 Reason #1&lt;/strong&gt;&lt;br&gt;
Each container is already &lt;strong&gt;exposed internally&lt;/strong&gt; on port 80, exposing the container means that we could access it &lt;strong&gt;from within the container's network&lt;/strong&gt;, which is also the one automatically created when we build the &lt;strong&gt;&lt;code&gt;docker-compose&lt;/code&gt;&lt;/strong&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📝 Reason #2&lt;/strong&gt;&lt;br&gt;
Mapping a container's port means that we could access it from the host machine, aka &lt;code&gt;localhost&lt;/code&gt;, so technically, if we created our container this way: &lt;code&gt;docker run -p 1111:80 strm/helloworld-http&lt;/code&gt; we could access it through &lt;code&gt;localhost:1111&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is all okay if you are accessing the container &lt;strong&gt;from the host machine&lt;/strong&gt;, namely, your machine, &lt;strong&gt;the one that has Docker installed&lt;/strong&gt;, but accessing the container from &lt;strong&gt;another container&lt;/strong&gt; is a whole another story.&lt;/p&gt;

&lt;p&gt;If you entered the bash terminal of the Linux container running Nginx and tried to ping &lt;code&gt;localhost:1111&lt;/code&gt; you'll get a nasty time-out error, because &lt;strong&gt;from within the container, &lt;code&gt;localhost&lt;/code&gt; or &lt;code&gt;127.0.0.1&lt;/code&gt; means the container itself, not the host machine&lt;/strong&gt;, so you'd want to figure out the host's IP Address that's accessible from inside Nginx's container in order to access the app on port &lt;code&gt;1111&lt;/code&gt;.&lt;br&gt;
We can skip all the hassle and just use the exposed port with Docker's DNS resolved hostname of the container.&lt;/p&gt;

&lt;p&gt;If you've reached up to this point, I've got some good news for you, we are finally about to be run our cluster, let's group our files in a single directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|-- HelloNginx
|  |-- docker-compose.yml
|  |-- Server
|  |  |-- nginx.conf
|  |  |-- Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... fire up your terminal, head to the root folder of the project &lt;strong&gt;/HelloNginx&lt;/strong&gt; where the compose file exists, and run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;foo@bar:~$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;docker-compose up
&lt;span class="go"&gt;•••
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... now head to Nginx Gateway URL: &lt;code&gt;localhost:8080&lt;/code&gt; (remember, we've set the port &lt;code&gt;8080&lt;/code&gt; within the &lt;code&gt;nginx.conf&lt;/code&gt; file) and you'll be welcomed with the first server in the cluster, keep refreshing and as you'll see, after each refresh, the page loads the name of the container from within the cluster application responded.&lt;/p&gt;

&lt;p&gt;You could take the full setup anywhere, maybe on the production machine too, just make sure to either copy your source code and build your images remotely on the machine, or you could just push your Docker images to a remote repository that can be accessible from the machine's Docker.&lt;/p&gt;

&lt;p&gt;Thanks a lot for taking the time to read through this series, I enjoyed writing and researching about this topic so much and I hope you enjoyed it too. See you soon 👋.&lt;/p&gt;

</description>
      <category>nginx</category>
      <category>docker</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
    <item>
      <title>One-Tap Deployments with Nginx and Docker: Configuring for Load Balancing ⚖</title>
      <dc:creator>Paula Fahmy</dc:creator>
      <pubDate>Fri, 20 Aug 2021 19:46:29 +0000</pubDate>
      <link>https://forem.com/paulafahmy/one-tap-deployments-with-nginx-and-docker-configuring-for-load-balancing-56b</link>
      <guid>https://forem.com/paulafahmy/one-tap-deployments-with-nginx-and-docker-configuring-for-load-balancing-56b</guid>
      <description>&lt;p&gt;Welcome back, in the &lt;a href="https://dev.to/paulafahmy/one-tap-deployments-with-nginx-and-docker-introduction-to-reverse-proxies-156c"&gt;previous article&lt;/a&gt;, we briefly introduced reverse proxies, and how we could use some of them, namely &lt;strong&gt;Nginx&lt;/strong&gt;, to load balance our app, for an &lt;strong&gt;easier scale-out and serving&lt;/strong&gt;. We also concluded the final architecture we'll be after as our final result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fza9stwfg77e0yvx51lf6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fza9stwfg77e0yvx51lf6.jpg" alt="Target Architecture" width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today, we'll jump right into the basics of &lt;strong&gt;Nginx&lt;/strong&gt;, so first up, make sure you have it installed on your machine.&lt;/p&gt;

&lt;p&gt;Once you have it installed, we can navigate to the configuration folder where all the magic really happens. Start off by navigating to this path &lt;code&gt;/etc/nginx/&lt;/code&gt; (if you're on Linux), you should be able to see an &lt;code&gt;nginx.conf&lt;/code&gt; file, launch it using your favorite text editor, and let's have a look in there.&lt;br&gt;
The file is not empty, and it has some default configurations already set, lets delete everything and start from scratch.&lt;/p&gt;

&lt;p&gt;We will learn today &lt;strong&gt;3 basic setups&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Serving local files&lt;/li&gt;
&lt;li&gt;Serving a hosted URL&lt;/li&gt;
&lt;li&gt;Accessing multiple instances through &lt;strong&gt;Load Balancing&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Serving Local Files
&lt;/h2&gt;

&lt;p&gt;The basic skeleton of a &lt;code&gt;nginx.conf&lt;/code&gt; file should (in most scenarios) contain these two directives.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;events&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll leave &lt;code&gt;events&lt;/code&gt; empty for now and focus on the other directive, &lt;code&gt;http&lt;/code&gt; which is where we'll be configuring &lt;strong&gt;Nginx as an HTTP server&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before we continue, note that we'll be stopping and starting Nginx multiple times whenever we apply changes to the &lt;code&gt;conf&lt;/code&gt; file, so if Nginx is not already running, run it using &lt;code&gt;nginx&lt;/code&gt; command. &lt;br&gt;
If it is already running and we need to restart it, we'll have to stop it using &lt;code&gt;nginx -s stop&lt;/code&gt; command, and then start it once again using &lt;code&gt;nginx&lt;/code&gt;. &lt;br&gt;
If you're on Linux make sure that you are running these commands in an elevated grant using &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's add an HTTP server, which listens on port &lt;strong&gt;&lt;code&gt;8080&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;events&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the file, restart Nginx and navigate to &lt;code&gt;localhost:8080&lt;/code&gt;, you should be able to see the following welcome screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ogwliss0r4sk90qvf7y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ogwliss0r4sk90qvf7y.png" alt="Welcome screen of Nginx" width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nginx has pulled this static HTML file from a default path because we've not yet set any. We'll be setting one now, I created a simple HTML file called &lt;code&gt;index.html&lt;/code&gt; in a folder called &lt;code&gt;Nginx_Article&lt;/code&gt; on the Desktop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
  &amp;lt;body&amp;gt;
    CUSTOM NGINX PAGE, YAY!
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Its full path should be &lt;strong&gt;&lt;code&gt;/home/{myusername}/Desktop/Nginx_Article/&lt;/code&gt;&lt;/strong&gt;, remember I'm using Linux, so this path might be a little bit different in your case, also don't forget to replace &lt;code&gt;{myusername}&lt;/code&gt; with your account's username (without the curly braces of course).&lt;br&gt;
Now let's configure Nginx to point to this web page when we hit port number &lt;code&gt;8080&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/home/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kn"&gt;myusername&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="n"&gt;/Desktop/Nginx_Article/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kn"&gt;events&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart Nginx and reload &lt;code&gt;localhost:8080&lt;/code&gt;, and you should be able to see our &lt;code&gt;index.html&lt;/code&gt; nicely served.&lt;/p&gt;

&lt;p&gt;Now, let's go &lt;strong&gt;a level higher&lt;/strong&gt;, what if we've got multiple directories that need to be served, not just a single root?&lt;br&gt;
Easy,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/images&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/home/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kn"&gt;myusername&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="n"&gt;/Desktop/Nginx_Article_Another_Directory/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

               &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/videos&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/path/to/another/root/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kn"&gt;events&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we used the &lt;code&gt;root&lt;/code&gt; directive inside a &lt;code&gt;location&lt;/code&gt; directive, this setup will ask Nginx to serve this directory: &lt;code&gt;/home/{myusername}/Desktop/Nginx_Article_Another_Directory/images&lt;/code&gt; in case &lt;code&gt;localhost:8080/images&lt;/code&gt; was requested.&lt;/p&gt;

&lt;p&gt;Don't forget to create the directory on your machine, and maybe add some images to test requesting them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important Note:&lt;/strong&gt; The directory &lt;code&gt;/images&lt;/code&gt; should have an &lt;code&gt;index.html&lt;/code&gt; file to be served by default &lt;strong&gt;OR&lt;/strong&gt; you'll have to ask for a specific file, for example: &lt;code&gt;localhost:8080/images/cat.jpg&lt;/code&gt;, and if no files are saved in &lt;code&gt;/images&lt;/code&gt;, the previous request will return &lt;strong&gt;forbidden status&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Another way of path mapping is using the &lt;strong&gt;&lt;code&gt;alias&lt;/code&gt;&lt;/strong&gt; directive as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/documents&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;alias&lt;/span&gt; &lt;span class="n"&gt;/home/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kn"&gt;myusername&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="n"&gt;/Desktop/Nginx_Article_Another_Directory/top_secret&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kn"&gt;events&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;alias&lt;/strong&gt; directive will ask Nginx to serve this directory: &lt;code&gt;home/{myusername}/Desktop/Nginx_Article_Another_Directory/top_secret&lt;/code&gt; in case &lt;code&gt;localhost:8080/documents&lt;/code&gt; was requested.&lt;/p&gt;

&lt;h4&gt;
  
  
  🧾 Let's Summarize
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;In case of &lt;code&gt;alias&lt;/code&gt; directory, we have to provide the full path to which Nginx was supposed to navigate, on the other hand, the &lt;code&gt;root&lt;/code&gt; directory just had the root path of the directory, and the location value is to be appended to that path.&lt;/li&gt;
&lt;li&gt;There is no actual directory named &lt;code&gt;/documents&lt;/code&gt; inside &lt;code&gt;Nginx_Article_Another_Directory&lt;/code&gt;, we are just creating an &lt;strong&gt;"alias"&lt;/strong&gt; for the directory &lt;code&gt;/top_secret&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Serving a hosted URL
&lt;/h2&gt;

&lt;p&gt;Let's say we're building a reverse proxy to &lt;strong&gt;&lt;a href="http://www.example.com" rel="noopener noreferrer"&gt;www.example.com&lt;/a&gt;&lt;/strong&gt;, we want users to view the site from our own domain, this could be done easily through the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://www.example.com/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;events&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try navigating to &lt;code&gt;localhost:8080&lt;/code&gt; after restarting Nginx, you should be able to see the exact same page as that of example.com.&lt;/p&gt;

&lt;p&gt;This could be used the same way when serving a locally hosted application (in our case, &lt;strong&gt;the backend application&lt;/strong&gt;) that's accessible through port &lt;strong&gt;&lt;code&gt;5000&lt;/code&gt;&lt;/strong&gt;,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://127.0.0.1:5000/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;events&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Accessing multiple instances through load balancing
&lt;/h2&gt;

&lt;p&gt;For this use case, we are going to deploy a simple Hello World app, with minimal setup, all you'll need is a working Docker setup on your machine.&lt;br&gt;
Head down to your favorite terminal app, and spin up 3 instances of the same app, each on its &lt;strong&gt;own container&lt;/strong&gt;, we'll be using the &lt;strong&gt;"helloworld" Docker Image&lt;/strong&gt;, which is exposed internally on port &lt;code&gt;80&lt;/code&gt;, when requested, it will print the Id of the container for the response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;foo@bar:~$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 1111:80 &lt;span class="nt"&gt;-d&lt;/span&gt; strm/helloworld-http
&lt;span class="go"&gt;478405720f2106d718edb1602812528ae53011cb196dc3731447c64d0bd8f2ff

&lt;/span&gt;&lt;span class="gp"&gt;foo@bar:~$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 1112:80 &lt;span class="nt"&gt;-d&lt;/span&gt; strm/helloworld-http
&lt;span class="go"&gt;a374ce45bf07b9747573e7feb1ae9742e72d2a31d74c2da3caa43abd5586a108

&lt;/span&gt;&lt;span class="gp"&gt;foo@bar:~$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 1113:80 &lt;span class="nt"&gt;-d&lt;/span&gt; strm/helloworld-http
&lt;span class="go"&gt;422efc18f418772cb96ea6088f2f801854ad4da21436da2c485f3ef80cca20ec
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Notice&lt;/strong&gt; that docker prints the ID of each container after each run command, also notice that we deployed 3 instances of the app, each accessible from outside its housing container through ports &lt;strong&gt;&lt;code&gt;:1111&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;:1112&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;:1113&lt;/code&gt;&lt;/strong&gt;. So for example, to navigate to the first instance of the app, you'll need to head to &lt;code&gt;localhost:1111&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;p&gt;Now let's play with the &lt;code&gt;conf&lt;/code&gt; file to set it up to balance an incoming load over our 3 instances.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kn"&gt;upstream&lt;/span&gt; &lt;span class="s"&gt;allinstances&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1111&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1112&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1113&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://allinstances/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;events&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks like we've added a new directive to our deck, &lt;code&gt;upstream&lt;/code&gt;, where our &lt;code&gt;proxy_pass&lt;/code&gt; now points at.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;upstream&lt;/code&gt; defines a cluster that you can proxy requests to. It's commonly used for defining a web server cluster for load balancing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Basically, this tells Nginx to &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Round-robin_scheduling" rel="noopener noreferrer"&gt;Round-Robin&lt;/a&gt;&lt;/strong&gt; each incoming request so that each server serves an equal number of requests. Each time you hit the refresh button, you are going to be greeted with a different server.&lt;/p&gt;

&lt;p&gt;You could get creative with the location directive, maybe you'd want to split users down to two &lt;code&gt;proxy_passes&lt;/code&gt;, so &lt;code&gt;/odd&lt;/code&gt; would navigate to &lt;code&gt;1111&lt;/code&gt; or &lt;code&gt;1113&lt;/code&gt;, and &lt;code&gt;/even&lt;/code&gt; would navigate to port &lt;code&gt;1112&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What if your application is saving user data in memory? You'd then need to make a user's session "sticky" by hashing IP addresses of the users so that a given user is guaranteed to hit the same server as long as his IP address did not change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;upstream&lt;/span&gt; &lt;span class="s"&gt;allinstances&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;ip_hash&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;&amp;lt; Will hash the user's IP address and resolve to a single server&lt;/span&gt;
    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1111&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1112&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1113&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After adding the &lt;code&gt;ip_hash&lt;/code&gt; command, no matter how much you refresh the page, you'll always be served by the same server.&lt;/p&gt;

&lt;p&gt;I think you now have the basics that can get you up and going. In our &lt;a href="https://dev.to/paulafahmy/one-tap-deployments-with-nginx-and-docker-serving-your-web-cluster-w-compose-29f6"&gt;next article&lt;/a&gt; we will be packaging the whole setup into containers (including Nginx) and deploying it through a single &lt;code&gt;docker-compose&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;I'd like to end this one with a small but powerful quote by Oscar Wilde, &lt;strong&gt;“Experience is the name everyone gives to their mistakes.”&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Keep up the good work 🚀. &lt;/p&gt;

</description>
      <category>nginx</category>
      <category>docker</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
    <item>
      <title>One-Tap Deployments with Nginx and Docker: Introduction to Reverse Proxies</title>
      <dc:creator>Paula Fahmy</dc:creator>
      <pubDate>Fri, 20 Aug 2021 19:46:04 +0000</pubDate>
      <link>https://forem.com/paulafahmy/one-tap-deployments-with-nginx-and-docker-introduction-to-reverse-proxies-156c</link>
      <guid>https://forem.com/paulafahmy/one-tap-deployments-with-nginx-and-docker-introduction-to-reverse-proxies-156c</guid>
      <description>&lt;p&gt;Yes, you read the title right, and it is what you think. If you've got minimal knowledge about Docker, you've certainly spelled out the famous Docker command &lt;strong&gt;&lt;code&gt;docker-compose up&lt;/code&gt;&lt;/strong&gt;, toss it with a &lt;code&gt;.yaml&lt;/code&gt; file, grouping an &lt;strong&gt;Nginx image&lt;/strong&gt; along with your &lt;strong&gt;application's image&lt;/strong&gt; and you've got yourself a running server.&lt;br&gt;
Of course, there would be some configurations left to do for the machine to start receiving requests from the outside world, but we'll focus more on how to get the engine running internally.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we're up to?
&lt;/h2&gt;

&lt;p&gt;Ok, so here's what we're up to, we've got a web application, and we want to deploy and serve the whole setup, hassle-free with one click (&lt;em&gt;disclaimer: not including those to configure the setup&lt;/em&gt; 😄).&lt;br&gt;
As you might already know, to be able to access the app from the outside, we need a &lt;strong&gt;"webserver"&lt;/strong&gt;, these can be any of (but not limited to) the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apache Server&lt;/li&gt;
&lt;li&gt;IIS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nginx (we'll choose this one)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm going to start by giving you a brief introduction about &lt;strong&gt;Nginx&lt;/strong&gt; and what it can actually do.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Nginx
&lt;/h2&gt;

&lt;p&gt;"Nginx is a web server that can also be used as a reverse proxy, load balancer, mail proxy, and HTTP cache." Igor Sysoev, the creator of the software, has publicly released it in 2004, and with its &lt;strong&gt;open-source license&lt;/strong&gt;, you can certainly use it for free.&lt;br&gt;
In the last paragraph, I introduced to this peaceful article a couple of new terminologies that you either have not heard about before or might have heard about them without knowing what they actually are. Let's discuss some of them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Proxies
&lt;/h3&gt;

&lt;p&gt;A Proxy is basically a server that &lt;strong&gt;requests on behalf of the client (you)&lt;/strong&gt;, in other words, the destination server (for instance, google.com) would receive the request not from you, but from the proxy server you're using.&lt;br&gt;
I could think of multiple reasons why any network setup would benefit from this technology.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzetrtztgh7vpgi8bik0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzetrtztgh7vpgi8bik0.jpg" alt="Normal Setup vs Proxy Setup" width="800" height="636"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So what are the benefits of a Proxy?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the top of my head, a proxy would instantly &lt;strong&gt;hide your IP address&lt;/strong&gt;, keeping you anonymous to the receiving end.&lt;/li&gt;
&lt;li&gt;A proxy could also cache the results of your requests, so instead of traveling all the way to the destination server, a proxy in the middle would go: "Hmmm, I think you've requested the weather 5 mins ago, here you go, it is still burning hot at 42°, no need to ask Google again."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep in mind, Nginx &lt;strong&gt;is not&lt;/strong&gt; a proxy, read on...&lt;/p&gt;

&lt;h3&gt;
  
  
  Reverse Proxies
&lt;/h3&gt;

&lt;p&gt;A Reverse Proxy on the other hand is &lt;em&gt;the opposite&lt;/em&gt; of a proxy.&lt;br&gt;
In case of a Proxy, the Server doesn't know the client, but in case of a Reverse Proxy, the client doesn't know the server, it is basically the other way around.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3bd78213y0no489vxyw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3bd78213y0no489vxyw.jpg" alt="Reverse Proxy Setup" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So what are the benefits of a Proxy?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Load Balancing&lt;/strong&gt;, which could be configured in multiple ways to ensure that running servers would distribute tasks in order to serve more users. In the previous example, Google had two servers, but only one responded, the other one could've been serving another user, or it might've been having a nap, it doesn't matter as long as the request has been served. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caching&lt;/strong&gt; works the other way around too. Google's Reverse Proxy would go: "Hmmm, I think you've just asked about the weather, nope, still 42°." without even passing the request to the actual Google servers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the main catch here is that (for most of the scenarios) a &lt;strong&gt;Proxy is installed and utilized by the Client&lt;/strong&gt; whereas a &lt;strong&gt;Reverse Proxy is installed and utilized by the Server&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before we continue, I want to point out that &lt;strong&gt;Hussein Nasser&lt;/strong&gt; made an &lt;a href="https://www.youtube.com/watch?v=SqqrOspasag" rel="noopener noreferrer"&gt;awesome video&lt;/a&gt; explaining the differences between Proxies and Reverse Proxies in an intuitive way, be sure to quickly watch it for an even better grasp.&lt;/p&gt;

&lt;h2&gt;
  
  
  The final architecture we're after
&lt;/h2&gt;

&lt;p&gt;After that brief intro, I think we are now aware that Nginx would be the server of choice, and what comes free with Nginx you ask? Yes, &lt;strong&gt;Load Balancing&lt;/strong&gt;. So let me try to capture the architecture we'll be going after in the following diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs57z8ocbuvozxtzkuc1v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs57z8ocbuvozxtzkuc1v.jpg" alt="Target Architecture" width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you might have figured out already, the architecture contains basically 3 main components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The client (end-user)&lt;/li&gt;
&lt;li&gt;A Database (hosted somewhere we don't care about for our context)&lt;/li&gt;
&lt;li&gt;Our &lt;strong&gt;Backend Server&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;This will be running 3 docker containers, 

&lt;ul&gt;
&lt;li&gt;Each having an instance of our backend application

&lt;ul&gt;
&lt;li&gt;Each app is accessible through an internal port number&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;We'll also be running an &lt;strong&gt;Nginx Server&lt;/strong&gt; pointing at each of the 3 instances in an attempt to access them through a load-balanced behavior (we'll discuss multiple approaches) from outside the Linux machine. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/paulafahmy/one-tap-deployments-with-nginx-and-docker-configuring-for-load-balancing-56b"&gt;upcoming article&lt;/a&gt;, I'll talk in detail about Nginx, and how to correctly configure it to our needs. See you on the other side of the world 🚀😄.&lt;/p&gt;

</description>
      <category>nginx</category>
      <category>docker</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Asynchronous C#: Cherry on the top 🍒 (Tips and Tricks)</title>
      <dc:creator>Paula Fahmy</dc:creator>
      <pubDate>Sat, 22 May 2021 06:20:28 +0000</pubDate>
      <link>https://forem.com/paulafahmy/asynchronous-c-cherry-on-the-top-tips-and-tricks-4eod</link>
      <guid>https://forem.com/paulafahmy/asynchronous-c-cherry-on-the-top-tips-and-tricks-4eod</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/paulafahmy/asynchronous-c-making-a-simple-cup-of-tea-13i"&gt;Part 1&lt;/a&gt; and &lt;a href="https://dev.to/paulafahmy/asynchronous-c-making-a-simple-cup-of-tea-part-2-1jcj"&gt;Part 2&lt;/a&gt; of the series, we took a nice dive to get us started in writing efficient async code in C#, I wanted to finalize the series with a couple of Tips and Tricks that will certainly come in handy in most development cases.&lt;/p&gt;

&lt;p&gt;Buckle up your seatbelts 🚀..&lt;/p&gt;

&lt;h3&gt;
  
  
  ✔ Tip #1
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;BoilWaterAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Starting the kettle"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Kettle Finished Boiling"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;PourWaterAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;boilWaterTask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;BoilWaterAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;boilWaterTask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Pouring boiling water."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Notice we are not awaiting the task!&lt;/span&gt;
    &lt;span class="nf"&gt;PourWaterAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Program Ended"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our first example, &lt;code&gt;PourWaterAsync()&lt;/code&gt; represents a &lt;code&gt;Task&lt;/code&gt; that is not awaited, although, the task consists of inner tasks that are indeed being awaited.&lt;/p&gt;

&lt;p&gt;Running this example will result in the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Starting the kettle
Program Ended
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The task &lt;code&gt;Task.Delay(3000)&lt;/code&gt; has started, but despite awaiting it, it did not get to reach the finishing line, and the kettle did not finish boiling.&lt;br&gt;
This behavior has resulted due to skipping the &lt;code&gt;await&lt;/code&gt; keyword in the top-level &lt;code&gt;Main()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Of course, rewriting these two lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;boilWaterTask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;BoilWaterAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;boilWaterTask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;BoilWaterAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;.. would give the same result.&lt;br&gt;
Always remember to "await" any task till reaching the very last calling point.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✔ Tip #2
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;BoilWaterAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// DON'T&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// A NO-NO&lt;/span&gt;
    &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// PLEASE DON'T ⛔&lt;/span&gt;
    &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAwaiter&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;GetResult&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The above three &lt;strong&gt;DON'Ts&lt;/strong&gt; will cause the application's main thread to be blocked till the tasks are finished, the app might stop responding or processing new requests till the synchronous wait is completed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ DO:&lt;/strong&gt;&lt;br&gt;
Embrace the asynchronous nature of the task, await it, and return the result. Tasks being propagated throughout your code &lt;strong&gt;is normal&lt;/strong&gt;, just try to delay doing so as much as you can.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✔ Tip #3
&lt;/h3&gt;

&lt;p&gt;Let's say we are implementing an interface, one of its methods requires a Task to be returned, &lt;strong&gt;BUT&lt;/strong&gt; the execution of the method itself does not require an asynchronous setup, it would not block the main thread and can run synchronously without problems.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;MyInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;DoSomethingAndReturnAString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MyInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;DoSomethingAndReturnAString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Some logic that does not need the await keyword&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Of course a compiler error, expecting Task&amp;lt;string&amp;gt; not a string&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can solve this issue with two approaches:&lt;/p&gt;

&lt;h4&gt;
  
  
  Solution 1 (a bad one 👎):
&lt;/h4&gt;

&lt;p&gt;Convert the method to be &lt;strong&gt;&lt;code&gt;async&lt;/code&gt;&lt;/strong&gt; &lt;strong&gt;(even though we do not need to await anything)&lt;/strong&gt;, and now we could return a string normally, right? &lt;strong&gt;DON'T ever do that!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The moment you mark a method as &lt;strong&gt;&lt;code&gt;async&lt;/code&gt;&lt;/strong&gt;, the compiler transforms your code into a &lt;strong&gt;state machine&lt;/strong&gt; that keeps track of things like yielding execution when an await is reached and resuming execution when a background job has finished. In fact, if you checked the IL &lt;em&gt;(Intermediate Language)&lt;/em&gt; generated from your code after marking a method as &lt;strong&gt;&lt;code&gt;async&lt;/code&gt;&lt;/strong&gt;, you'll notice that the function has turned into an entire class for that matter.&lt;/p&gt;

&lt;p&gt;So even on synchronous method marked with async (without await inside), a state machine will still be generated anyways and the code which could potentially be inlined and executed much faster will be generating additional complexity for state machine management.&lt;/p&gt;

&lt;p&gt;📝 &lt;strong&gt;That's why it's so important to mark methods as async if and only if there is await inside.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Solution 2 (much better 👍):
&lt;/h4&gt;

&lt;p&gt;Instead: &lt;code&gt;return Task.FromResult("result");&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let's take another example:&lt;/p&gt;

&lt;p&gt;We have an HTTP client retrieving some text from an external web source,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetFromWebsite&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetStringAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my.website.com"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="err"&gt;•••&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the objective is to only start retrieving the string from the website, then the best way to do it is to return the task of &lt;code&gt;GetStringAsync()&lt;/code&gt; as is, and &lt;strong&gt;do not await it here&lt;/strong&gt;, it boils down to the same reason of skipping the aimless creation of a state machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetFromWebsite&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetStringAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my.website.com"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only case you'd want to await the call is that you want to perform some logic on the result &lt;strong&gt;inside&lt;/strong&gt; the method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Notice that we marked the method as async&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetFromWebsiteAndValidate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetStringAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my.website.com"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Perform some logic on the result&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember, if you used the word "and" while describing what a method does, something might not be right.&lt;br&gt;
Example: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"My method is doing &lt;em&gt;x&lt;/em&gt; and &lt;em&gt;y&lt;/em&gt; and &lt;em&gt;z&lt;/em&gt;" (NO-NO ⛔)&lt;/li&gt;
&lt;li&gt;"I have 3 methods, one for doing &lt;em&gt;x&lt;/em&gt;, another for &lt;em&gt;y&lt;/em&gt;, and the last for &lt;em&gt;z&lt;/em&gt;" (YES ✔)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This will make your life much easier when trying to apply unit tests to your code.&lt;/p&gt;

&lt;p&gt;So a rule of thumbs 👍 to note down here:&lt;br&gt;
Only &lt;strong&gt;await&lt;/strong&gt; when you &lt;strong&gt;absolutely need&lt;/strong&gt; the result of the task.&lt;br&gt;
The async keyword does not run the method on a different thread, or do any other kind of hidden magic, hence, only mark a method as &lt;strong&gt;async&lt;/strong&gt; when you need to use the keyword &lt;strong&gt;await&lt;/strong&gt; in it.&lt;/p&gt;

&lt;p&gt;A couple of notes to always remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;strong&gt;async&lt;/strong&gt; function can return either on of the three types: &lt;code&gt;void&lt;/code&gt;, &lt;code&gt;Task&lt;/code&gt;, or &lt;code&gt;Task&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A function is "awaitable" because it returns a &lt;code&gt;Task&lt;/code&gt; or a &lt;code&gt;Task&amp;lt;T&amp;gt;&lt;/code&gt;, not because it is marked &lt;code&gt;async&lt;/code&gt;, so we can &lt;code&gt;await&lt;/code&gt; a function that &lt;strong&gt;is not async&lt;/strong&gt; (a one just returning &lt;code&gt;Task&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;You cannot &lt;code&gt;await&lt;/code&gt; a function returning &lt;code&gt;void&lt;/code&gt;, hence, you should always return a &lt;code&gt;Task&lt;/code&gt; unless there is an absolute reason not to do so (a caller to the function expects a void return type), or that the function itself is a top-level function and there is no way other functions will be able to call it..&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✔ Tip #4
&lt;/h3&gt;

&lt;p&gt;We established that long-running tasks should always execute asynchronously, these tasks can fall down into two main categories, &lt;strong&gt;I/O-Bound&lt;/strong&gt; and &lt;strong&gt;CPU-Bound&lt;/strong&gt;. A task is said to be I/O bound when the time taken for it to complete is determined principally by the period spent waiting for input/output operations to be completed. In contrast, a CPU-Bound task is a task that's time of completion is determined principally by the speed of the central processor, examples for these would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I/O Bound Tasks:

&lt;ul&gt;
&lt;li&gt;Requesting data from the network&lt;/li&gt;
&lt;li&gt;Accessing the database&lt;/li&gt;
&lt;li&gt;Reading/Writing to a file system&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;CPU Bound Tasks: Generally performing an expensive calculation such as:

&lt;ul&gt;
&lt;li&gt;Graphics Rendering&lt;/li&gt;
&lt;li&gt;Video Compression&lt;/li&gt;
&lt;li&gt;Heavy mathematical computations&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Generally, whenever you got an I/O Bound &lt;code&gt;Task&lt;/code&gt; or &lt;code&gt;Task&amp;lt;T&amp;gt;&lt;/code&gt; at hands, &lt;code&gt;await&lt;/code&gt; it in an &lt;code&gt;async&lt;/code&gt; method. For CPU-bound code, you await an operation that is started on a background thread with the &lt;strong&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.run" rel="noopener noreferrer"&gt;&lt;code&gt;Task.Run&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; method. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note 📝:&lt;/strong&gt;&lt;br&gt;
Make sure you analyzed the execution of your CPU-Bound code, and be mindful of the context switching overhead when multithreading, it might be not so costly after all in comparison.&lt;/p&gt;

&lt;p&gt;Okay, that's all I have for y'all today.&lt;br&gt;
Keep Coding 😉&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>webdev</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Asynchronous C#: Making a simple Cup of Tea (Part 2)</title>
      <dc:creator>Paula Fahmy</dc:creator>
      <pubDate>Sat, 22 May 2021 06:18:30 +0000</pubDate>
      <link>https://forem.com/paulafahmy/asynchronous-c-making-a-simple-cup-of-tea-part-2-1jcj</link>
      <guid>https://forem.com/paulafahmy/asynchronous-c-making-a-simple-cup-of-tea-part-2-1jcj</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/paulafahmy/asynchronous-c-making-a-simple-cup-of-tea-13i"&gt;Last time&lt;/a&gt;, we had an introductory walkthrough to C#'s way of "asynchronizing" code. We talked about the difference between "multithreading" and "multiprocessing", and we gave an example to illustrate the subject where we made a simple cup of tea.&lt;/p&gt;

&lt;p&gt;Ok, let's open the hood once more and get our hands dirty. The code now supports asynchronous operation and our UI does not freeze when we wait for a task. Next up, let's introduce some minor changes to allow our program to finish preparing our tea faster.&lt;/p&gt;

&lt;p&gt;Some notes to remember from the previous part of the article before we move on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calling an async function (generally: a function returning a &lt;code&gt;Task&lt;/code&gt; or a &lt;code&gt;Task&amp;lt;&amp;gt;&lt;/code&gt;) results in the creation of a "&lt;strong&gt;hot task&lt;/strong&gt;", a task that runs immediately once created.&lt;/li&gt;
&lt;li&gt;At some point, we'll have to &lt;strong&gt;&lt;code&gt;await&lt;/code&gt;&lt;/strong&gt; the task to get its result.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Addressing Synchronous code Issues
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Issue #2: Slow Execution
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;MakeTeaAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;water&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;BoilWaterAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// takes 3 seconds&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;PrepareCupsAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 3 seconds for each cup (6 seconds in total)&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Pouring &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;water&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; into &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cups&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;cups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"cups with tea"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;warmMilk&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;WarmupMilkAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// this line takes 5 seconds&lt;/span&gt;
    &lt;span class="c1"&gt;// ~14 seconds in total..&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Adding &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;warmMilk&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; into &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cups&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we can split "awaiting" the task from creating it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;MakeTeaAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;waterBoilingTask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;BoilWaterAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;water&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;waterBoilingTask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;preparingCupsTask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;PrepareCupsAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;cups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;preparingCupsTask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Pouring &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;water&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; into &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cups&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;cups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"cups with tea"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;warmingMilkTask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;WarmupMilkAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;warmMilk&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;warmingMilkTask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Adding &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;warmMilk&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; into &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cups&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is important to note down the following:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The composition of an asynchronous operation followed by synchronous work is an asynchronous operation. Stated another way, if any portion of an operation is asynchronous, the entire operation is asynchronous.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now let's reorder the logic.&lt;br&gt;
Since the tasks are independent of each other, we can launch them all together at once. We know for a fact that we can't pour the milk unless we have the boiled water poured on top of the tea first.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;MakeTeaAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;waterBoilingTask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;BoilWaterAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;preparingCupsTask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;PrepareCupsAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;warmingMilkTask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;WarmupMilkAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;preparingCupsTask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;water&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;waterBoilingTask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Pouring &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;water&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; into &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cups&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;cups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"cups with tea"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;warmMilk&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;warmingMilkTask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Adding &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;warmMilk&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; into &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cups&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start the kettle
Waiting for the kettle
Taking cup #1 out.
Putting tea and sugar in the cup
Pouring milk into a container
Putting the container in microwave
Warming up the milk
Taking cup #2 out.
Putting tea and sugar in the cup
Kettle Finished Boiling
Finished warming up the milk
Finished preparing the cups
Pouring Hot water into cups
Adding Warm Milk into cups with tea
-------------------------------
Time Elapsed: 6.1258995999999994 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that's a considerable boost in performance, about a 230% speed increase to be specific.&lt;br&gt;
All we did was start the kettle, start preparing the cups, and start warming the milk all in parallel. Preparing cup #1 would take 3 seconds, and instead of waiting, we started warming the milk to buy some time.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Synchronous Operation&lt;/th&gt;
&lt;th&gt;Asynchronous Operation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9gm2mru8gblz98716hpv.JPG" alt="Alt Text" width="756" height="719"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05hgym5tnmp0cvnjbpyq.JPG" alt="Parallel Waterfall Illustration" width="800" height="397"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I think we can enhance a bit more, how about we refactor &lt;code&gt;PrepareCupsAsync()&lt;/code&gt;? We can prepare multiple cups in parallel!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;PrepareCupsAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;numberOfCups&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;eachCupTask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Enumerable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numberOfCups&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Taking cup #&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; out."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Putting tea and sugar in the cup"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;ToArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WhenAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eachCupTask&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finished preparing the cups"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"cups"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using LINQ, we created a new IEnumerable of Tasks. All the created tasks ran immediately the moment we enumerated the IEnumerable using the &lt;code&gt;.ToArray()&lt;/code&gt; call. Finally, we waited for the tasks altogether using WhenAll().&lt;br&gt;
In other use cases, you may find it useful to use the result of only the first task to finish disregarding the other tasks. In such cases, you'd want to use &lt;code&gt;.WhenAny()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IMPORTANT NOTE:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Although it's less code, use caution when mixing LINQ with asynchronous code. Because LINQ uses deferred (lazy) execution, async calls won't happen immediately as they do in a &lt;code&gt;foreach&lt;/code&gt; loop unless you force the generated sequence to iterate with a call to &lt;code&gt;.ToList()&lt;/code&gt; or &lt;code&gt;.ToArray()&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now let's check the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start the kettle
Waiting for the kettle
Taking cup #1 out.
Putting tea and sugar in the cup
Taking cup #2 out.
Putting tea and sugar in the cup
Pouring milk into a container
Putting the container in microwave
Warming up the milk
Kettle Finished Boiling
Finished preparing the cups
Pouring Hot water into cups
Finished warming up the milk
Adding Warm Milk into cups with tea
-------------------------------
Time Elapsed: 5.1878251 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We went down from 6 seconds to 5 seconds, and that's the best we could get out of the flow because warming milk takes 5 seconds itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pop Quiz! 📃&lt;/strong&gt;&lt;br&gt;
Q: Let's say your friends are coming over for a movie night 🍿, and you are making 10 cups of tea instead of just 2 &lt;code&gt;PrepareCupsAsync(10)&lt;/code&gt;, how much time do you think it'd take?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start the kettle
Waiting for the kettle
Taking cup #1 out.
Putting tea and sugar in the cup
•••
Taking cup #10 out.
Putting tea and sugar in the cup
Pouring milk into a container
Putting the container in microwave
Warming up the milk
Kettle Finished Boiling
Finished preparing the cups
Pouring Hot water into cups
Finished warming up the milk
Adding Warm Milk into cups with tea
-------------------------------
Time Elapsed: 5.1923364 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yep, you guessed it right, it'd still take no more than 5 seconds. That is how scalable our code has been refactored to be.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Async/Await multithreaded?
&lt;/h3&gt;

&lt;p&gt;Unlike other languages, Javascript for example, which uses async single threads, .NET framework is multithreaded, and in this instance, it can be both single and multithreaded, or either. Unless you're really trying to share data between multiple threads, you usually do not need to worry about it, but for mere pleasure, let's investigate which thread is actually working on each piece of code.&lt;/p&gt;

&lt;p&gt;I added this simple helper method to state the ID of the current thread when writing to console..&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;WriteLineWithCurrentThreadId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;textToPrint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
            &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Thread #&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentThread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ManagedThreadId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; | &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;textToPrint&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;.. and then I replaced each &lt;code&gt;Console.WriteLine()&lt;/code&gt; with &lt;code&gt;WriteLineWithCurrentThreadId()&lt;/code&gt;.&lt;br&gt;
Here are the results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thread #1 | Start the kettle
Thread #1 | Waiting for the kettle
Thread #1 | Taking cup #1 out.
Thread #1 | Putting tea and sugar in the cup
Thread #1 | Taking cup #2 out.
Thread #1 | Putting tea and sugar in the cup
Thread #1 | Pouring milk into a container
Thread #1 | Putting the container in microwave
Thread #1 | Warming up the milk
Thread #4 | Kettle Finished Boiling
Thread #5 | Finished preparing the cups
Thread #5 | Pouring Hot water into cups
Thread #4 | Finished warming up the milk
Thread #4 | Adding Warm Milk into cups with tea
-------------------------------
Time Elapsed: 5.2266067000000005 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;So what is happening in here?&lt;/strong&gt;&lt;br&gt;
We have a bunch of threads lying around in a pool, a &lt;strong&gt;thread pool&lt;/strong&gt;, all the threads are pretty much the same, they're all available and in the same context, some of them are currently working on something, others are idle, waiting for a task to be assigned to. &lt;br&gt;
Our console application will just grab whichever one might be available. And occasionally they switch sometimes they don't, and &lt;strong&gt;after an await&lt;/strong&gt; it's going to pick whatever thread that's available from the same context from the thread pool, and then continue on that.&lt;br&gt;
In the case of a WPF program, &lt;strong&gt;there's only one thread that can write to the UI&lt;/strong&gt;. So in that instance, the continuation runs on exactly the same thread to make sure that it can update the windows correctly.&lt;/p&gt;

&lt;p&gt;Phew! That was a lot to take in, right?&lt;br&gt;
Be sure to read the article a couple of times, and try to take the source code for a test drive to see the effects yourself, also check the &lt;a href="https://dev.to/paulafahmy/asynchronous-c-cherry-on-the-top-tips-and-tricks-4eod"&gt;last part&lt;/a&gt; of the series, I wrote down some tips and tricks that could be applied in almost any coding situation.&lt;/p&gt;

&lt;p&gt;Best of luck 🙌.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Asynchronous C#: Making a simple Cup of Tea</title>
      <dc:creator>Paula Fahmy</dc:creator>
      <pubDate>Sat, 22 May 2021 06:17:25 +0000</pubDate>
      <link>https://forem.com/paulafahmy/asynchronous-c-making-a-simple-cup-of-tea-13i</link>
      <guid>https://forem.com/paulafahmy/asynchronous-c-making-a-simple-cup-of-tea-13i</guid>
      <description>&lt;p&gt;Years ago, programs ran sequentially, line by line and function by function. Only one &lt;em&gt;task&lt;/em&gt; processing at a given unit of time. If a function relied on another function, it had to wait till it got the result from that function before continuing to process, even if it meant that the application's main thread would get blocked for an amount of time, waiting for some network call to return a response or for a piece of work that requires a heavy calculation to yield a result.&lt;/p&gt;

&lt;p&gt;For the past couple of years, a typical device running almost any type of operating systems have at least a two, eight, or even 16 cores chip, where each core can focus on a task (or multiple tasks at once in some cases), resulting in the ability to process more bits and bytes in a fewer number of precious microseconds, allowing what's called "Asynchrony", or Asynchronous Programming of a given group of tasks.&lt;/p&gt;

&lt;p&gt;Asynchrony refers to the occurrence of events independent of the main program flow, they typically take place concurrently with program execution, without the program blocking to wait for results. Doing so provides a degree of parallelism, effectively using the available resources to achieve a target sooner than the &lt;strong&gt;synchronous version of the same piece of code&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Threads vs Processes
&lt;/h2&gt;

&lt;p&gt;Whenever we talk about asynchrony, we have to mention either one of these two terms, so what are the differences between the two?&lt;/p&gt;

&lt;p&gt;A process is an executing instance of a program, it has its own memory space, registers, etc. On the other hand, a thread is essentially one of the components of a given process, meaning that a process can have multiple threads running concurrently.&lt;br&gt;
The conversation can't end without addressing "multi-&lt;strong&gt;processing&lt;/strong&gt;" and "multi-&lt;strong&gt;threading&lt;/strong&gt;", let me share a nice comparison between them from &lt;a href="https://www.guru99.com/difference-between-multiprocessing-and-multithreading.html" rel="noopener noreferrer"&gt;guru99.com&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Topic&lt;/th&gt;
&lt;th&gt;MultiProcessing&lt;/th&gt;
&lt;th&gt;MultiThreading&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Definition&lt;/td&gt;
&lt;td&gt;Is a system that has more than two processors&lt;/td&gt;
&lt;td&gt;Is a program execution technique that allows a single process to have multiple code segments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What is it about&lt;/td&gt;
&lt;td&gt;Improves the &lt;strong&gt;reliability&lt;/strong&gt; of the system&lt;/td&gt;
&lt;td&gt;Each thread runs parallel to each other&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resources&lt;/td&gt;
&lt;td&gt;The creation of a process is slow and resource-consuming&lt;/td&gt;
&lt;td&gt;The creation of a thread is economical in time and resource.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Be sure to check out the full comparison: &lt;a href="https://www.guru99.com/difference-between-multiprocessing-and-multithreading.html" rel="noopener noreferrer"&gt;Multithreading vs Multiprocessing at Guru99&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So long story short, the main difference between the two is &lt;strong&gt;whether they share memory or not&lt;/strong&gt;. Processes do not share memory, thus operating independently while threads &lt;em&gt;(of the same process)&lt;/em&gt; on the other hand, share the same memory allocated to their housing process.&lt;/p&gt;

&lt;p&gt;A great real-life example would be how you're currently reading this article on &lt;strong&gt;Chrome&lt;/strong&gt;, odds are you currently have more than one tab lying around in your browser, each in its own process, a tab would not care about its neighboring tab, and a tab could (&lt;em&gt;God forbid&lt;/em&gt;) crash without the whole app crashing, &lt;strong&gt;that's "multiprocessing"&lt;/strong&gt;.&lt;br&gt;
Now try to reload the page (and let's assume your connection isn't that fast), notice how you can move or resize the window normally while waiting for the page to load, &lt;strong&gt;that's "multithreading"&lt;/strong&gt;, your app is responsive even though it is waiting for a task (or a thread) to return a result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujcmrlydo5t4ww9l92ap.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujcmrlydo5t4ww9l92ap.jpg" alt="Muliple processes in Google Chrome" width="800" height="687"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Async and Await
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In C# 5, Microsoft introduced a simplified approach to asynchronous programming in .NET Framework, Where all the heavy lifting that was done by the developer is now done by the compiler.&lt;/p&gt;

&lt;p&gt;The framework is wrapped in what's called: "Task asynchronous programming model" or &lt;strong&gt;TAP&lt;/strong&gt; for short. The model is an abstraction layer over asynchronous code. You write your logic as a sequence of steps normally, and the compiler performs some transformations in the background because these statements return a &lt;strong&gt;&lt;code&gt;Task&amp;lt;&amp;gt;&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Asynchronous methods mainly look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;DoSomethingAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// In the Real World, we would actually do something...&lt;/span&gt;
  &lt;span class="c1"&gt;// For this example, we're just going to (asynchronously) wait 100ms.&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Synchronous Example
&lt;/h3&gt;

&lt;p&gt;A perfect example that illustrates asynchronous work would be preparing a cup of tea, the job consists of four main tasks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Preparing the cups by putting tea and sugar&lt;/li&gt;
&lt;li&gt;Boiling the water&lt;/li&gt;
&lt;li&gt;Warming up some fresh milk&lt;/li&gt;
&lt;li&gt;Adding all the ingredients together in one nice cup of tea.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One person (or thread) can handle all these tasks. He can prepare the cups asynchronously by starting the next task before the first one completes. As soon as you start the kettle, you can begin warming up the milk. Once the water boils, you can pour it into the cup and then add some milk.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;BoilWater&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Start the kettle"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Waiting for the kettle"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Kettle Finished Boiling"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hot water"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;PrepareCups&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;numberOfCups&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;numberOfCups&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Taking cup #&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; out."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Putting tea and sugar in the cup"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finished preparing the cups"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"cups"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;WarmupMilk&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Pouring milk into a container"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Putting the container in microwave"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Warming up the milk"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finished warming up the milk"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Warm Milk"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;MakeTea&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;water&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;BoilWater&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;PrepareCups&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Pouring &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;water&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; into &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cups&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;cups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"cups with tea"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;warmMilk&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;WarmupMilk&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Adding &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;warmMilk&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; into &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cups&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// App's main entry point.&lt;/span&gt;
    &lt;span class="nf"&gt;MakeTea&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// Stopwatch logic is hidden for simplicity&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, preparing the cups would take 3 seconds for each cup (6 for both cups), boiling the water would take another 3 seconds, warming up some milk would take 5 seconds, resulting in a total of 14 seconds, here is the output of our program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start the kettle
Waiting for the kettle
Kettle Finished Boiling
Taking cup #1 out.
Putting tea and sugar in the cup
Taking cup #2 out.
Putting tea and sugar in the cup
Finished preparing the cups
Pouring Hot water into cups
Pouring milk into a container
Putting the container in microwave
Warming up the milk
Finished warming up the milk
Adding Warm Milk into cups with tea
-------------------------------
Time Elapsed: 14.1665602 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpzabad17yqybkujyabg7.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpzabad17yqybkujyabg7.JPG" alt="Synchronous waterfall graph" width="756" height="719"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, waiting for the cups to be prepared might risk boiled water to cool down, the exact same case can take place while waiting for the milk to get warm, the nice hot cup of tea might have to sit and wait on the counter till the milk is ready, this represents &lt;strong&gt;our first concern.&lt;/strong&gt; &lt;br&gt;
&lt;strong&gt;Another problem&lt;/strong&gt; might arise the moment this console application is converted to a GUI application. Try to cancel, minimize, or even interact with the window and you'll instantly notice something is not right, our application will freeze the second we "wait" for a task to finish, warming up a simple cup of milk would not result in the best user experience.&lt;/p&gt;

&lt;p&gt;What happened in our current version is analogous to a chef being focused on exactly one job, tapping his feet on the ground, looking at his watch every now and then, so eager, waiting for it to get done. He won't respond to his fellow chef asking for the current time, he won't even answer to his boss. That's not the best behavior to get out of our chef (or the thread, technically speaking).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F96qw35nvp69jtwl6ixky.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F96qw35nvp69jtwl6ixky.jpg" alt="Stuck Windows Form" width="645" height="488"&gt;&lt;/a&gt;&lt;br&gt;
As you can see, upon converting the console app into a windows forms application (GUI), clicking on the "Make Tea" button instantly stalls the window. The block is not released until the synchronous wait is completed.&lt;/p&gt;
&lt;h3&gt;
  
  
  Addressing Synchronous code Issues
&lt;/h3&gt;

&lt;p&gt;Now, let's address each issue.&lt;/p&gt;
&lt;h4&gt;
  
  
  Issue #1: Frozen UI (generally, the main thread)
&lt;/h4&gt;

&lt;p&gt;When we write client applications, we want the UI to be as responsive as possible, the last thing we want is our app freezing here and there while it's downloading data from the web. We need to modify our app to utilize asynchrony.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't Block, Await Instead&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's start with the helping functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;BoilWaterAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Start the kettle"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Waiting for the kettle"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Kettle Finished Boiling"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hot water"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;PrepareCupsAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;numberOfCups&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;numberOfCups&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Taking cup #&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; out."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Putting tea and sugar in the cup"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finished preparing the cups"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"cups"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;WarmupMilkAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Pouring milk into a container"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Putting the container in microwave"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Warming up the milk"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finished warming up the milk"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Warm Milk"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;MakeTeaAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;water&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;BoilWaterAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;PrepareCupsAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Pouring &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;water&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; into &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cups&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;cups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"cups with tea"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;warmMilk&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;WarmupMilkAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Adding &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;warmMilk&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; into &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cups&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we'll need to modify our entry point too&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// App's main entry point.&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;MakeTea&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// Stopwatch logic is hidden for simplicity&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And when we try running the app again, we get this output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start the kettle
Waiting for the kettle
Kettle Finished Boiling
Taking cup #1 out.
Putting tea and sugar in the cup
Taking cup #2 out.
Putting tea and sugar in the cup
Finished preparing the cups
Pouring Hot water into cups
Pouring milk into a container
Putting the container in microwave
Warming up the milk
Finished warming up the milk
Adding Warm Milk into cups with tea
-------------------------------
Time Elapsed: 14.1202222 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Something is not just right here. &lt;strong&gt;The elapsed time is roughly the same as our initial synchronous version!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ok, here is the thing, this code doesn't block. While we're waiting for the water to boil, the chef would still start the kettle, stare at it while it heats up, but at least now, he'll respond to his partners, the UI thread is now responsive while waiting for a task to finish.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When you write server programs, you don't want threads blocked. Those threads could be serving other requests. Using synchronous code when asynchronous alternatives exist hurts your ability to scale out less expensively. You pay for those blocked threads.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For some use cases, this is all we need for our app to be acceptable for the user.&lt;/p&gt;

&lt;p&gt;Remember, we are still addressing the first issue, the code still needs to take advantage of some features of &lt;strong&gt;TAP&lt;/strong&gt; asynchronous model, but first, let's take a quick look under the hood.&lt;/p&gt;

&lt;h5&gt;
  
  
  Awaitable and Tasks
&lt;/h5&gt;

&lt;p&gt;I highlighted exactly what was altered in order for the &lt;code&gt;BoilWater()&lt;/code&gt; method to become &lt;strong&gt;&lt;code&gt;BoilWaterAsync()&lt;/code&gt;&lt;/strong&gt; &lt;/p&gt;

&lt;pre&gt;
static async Task BoilWaterAsync()
{
    Console.WriteLine("Start the kettle");
    Console.WriteLine("Waiting for the kettle");
    await Task.Delay(3000); // We also removed the .Wait() call

    Console.WriteLine("Kettle Finished Boiling");

    return "Hot water";
}
&lt;/pre&gt;

&lt;p&gt;Now let's take a couple of notes:&lt;/p&gt;

&lt;p&gt;As we observed the results, the method executed just like any other method, &lt;strong&gt;synchronously&lt;/strong&gt;, until it hits the &lt;strong&gt;"await keyword"&lt;/strong&gt;, this is where things can get &lt;strong&gt;asynchronous&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;await&lt;/code&gt; keyword expects an &lt;strong&gt;"awaitable"&lt;/strong&gt; (in our case, the &lt;strong&gt;&lt;code&gt;Task&amp;lt;&amp;gt;&lt;/code&gt;&lt;/strong&gt; resulted from the &lt;code&gt;Delay&lt;/code&gt; method), then it examines whether the awaitable has already completed or not, if &lt;code&gt;await&lt;/code&gt; sees that the awaitable has not completed, then it acts &lt;strong&gt;asynchronously&lt;/strong&gt;, waits for the awaitable to continue till it finally completes, only then, the method just &lt;strong&gt;continues running synchronously again&lt;/strong&gt;, just like a regular method. &lt;br&gt;
Hold on to this point in your head, I promise it's going to get clearer.&lt;/p&gt;

&lt;p&gt;Now, let me modify the &lt;code&gt;MakeTeaAsync()&lt;/code&gt; method once again, functionality stays the same:&lt;/p&gt;

&lt;pre&gt;
static async Task MakeTeaAsync()
{

    //var water = await BoilWaterAsync();
    Task waterTask = BoilWaterAsync();
    string water = await waterTask;
    var cups = await PrepareCupsAsync(2);
    Console.WriteLine($"Pouring {water} into {cups}");

    cups = "cups with tea";

    var warmMilk = WarmupMilkAsync();
    Console.WriteLine($"Adding {warmMilk} into {cups}");
}
&lt;/pre&gt;

&lt;p&gt;Recall that &lt;code&gt;BoilWaterAsync()&lt;/code&gt; returns a &lt;code&gt;Task&amp;lt;string&amp;gt;&lt;/code&gt;, not just a &lt;code&gt;string&lt;/code&gt;. A task is an object that represents some work that should be done, some sort of a promise, there &lt;em&gt;should&lt;/em&gt; be a result at some point in the future. A &lt;code&gt;Task&lt;/code&gt; is an awaitable, and hence it can be "awaited" using the keyword (you guessed it), &lt;strong&gt;&lt;code&gt;await&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pop Quiz! 📃&lt;/strong&gt;&lt;br&gt;
Q: Why did we use &lt;code&gt;Task&amp;lt;&amp;gt;&lt;/code&gt; as the return type?&lt;br&gt;
A: Because we might need to &lt;code&gt;await&lt;/code&gt; the task to finish at some point.&lt;/p&gt;

&lt;p&gt;Q: Why do we need to &lt;code&gt;await&lt;/code&gt; the &lt;code&gt;Task&lt;/code&gt;?&lt;br&gt;
A: Because we need a result extracted from the &lt;code&gt;Task&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;One important concept to notice, the following line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;waterTask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;BoilWaterAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;.. caused the creation of what's called a &lt;strong&gt;"hot" task 🔥&lt;/strong&gt;, which is a task that starts running immediately the moment it gets created, so if we decide to add more logic to the function&lt;/p&gt;

&lt;pre&gt;
static async Task MakeTeaAsync()
{
    •••
    
    Task waterTask = BoilWaterAsync();
    
    // Some long-running synchronous for loop
    // 
    // ... still looping aimlessly
    // 
    // ummm, okay, done 👍
    
    string water = await waterTask;
    
    •••
}
&lt;/pre&gt;

&lt;p&gt;.. by the time we reach the &lt;code&gt;await&lt;/code&gt; keyword, the &lt;code&gt;Task&lt;/code&gt; might have already started, and finished. &lt;code&gt;await&lt;/code&gt; will just have to extract the result from the &lt;code&gt;Task&lt;/code&gt;, and we'd be good to go, synchronously of course (the rest of the function). This called &lt;strong&gt;Task Composition&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The previous code snippet showed us that we can use &lt;code&gt;Task&lt;/code&gt; or &lt;code&gt;Task&amp;lt;&amp;gt;&lt;/code&gt; objects to hold running tasks, then we await each task before using its result.&lt;/p&gt;

&lt;p&gt;One final note to write down, &lt;strong&gt;context switching&lt;/strong&gt;...&lt;br&gt;
After the awaitable (&lt;code&gt;waterTask&lt;/code&gt;) is completed, the remainder of the async function (&lt;code&gt;MakeTeaAsync&lt;/code&gt;) will execute on a "context" that was captured before the &lt;code&gt;await&lt;/code&gt; returned, &lt;strong&gt;but what exactly is a "context"?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you’re on a UI thread, then it’s a UI context.&lt;/li&gt;
&lt;li&gt;If you’re responding to an ASP.NET request, then it’s an ASP.NET request context.&lt;/li&gt;
&lt;li&gt;Otherwise, it’s usually a thread pool context.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a quick example (taken from Stephen Cleary's &lt;a href="https://blog.stephencleary.com/2012/02/async-and-await.html" rel="noopener noreferrer"&gt;blog post&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// WinForms example&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DownloadFileButton_Click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Since we asynchronously wait, the UI thread is not blocked by the file download.&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;DownloadFileAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileNameTextBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Since we resume on the UI context, we can directly access UI elements.&lt;/span&gt;
    &lt;span class="n"&gt;resultTextBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"File downloaded!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ASP.NET example&lt;/span&gt;
&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;MyButton_Click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Since we asynchronously wait, the ASP.NET thread is not blocked by the file download.&lt;/span&gt;
    &lt;span class="c1"&gt;// This allows the thread to handle other requests while we're waiting.&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;DownloadFileAsync&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt;

    &lt;span class="c1"&gt;// Since we resume on the ASP.NET context, we can access the current request.&lt;/span&gt;
    &lt;span class="c1"&gt;// We may actually be on another *thread*, but we have the same ASP.NET request context.&lt;/span&gt;
    &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"File downloaded!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To sum up, I'd like to (again) quote Stephen Cleary:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I like to think of “await” as an “asynchronous wait”. That is to say, the async method pauses until the awaitable is complete (so it waits), but the actual thread is not blocked (so it’s asynchronous)."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://dev.to/paulafahmy/asynchronous-c-making-a-simple-cup-of-tea-part-2-1jcj"&gt;Next up&lt;/a&gt;, we'll have another attempt to refactor our tea maker in order for it to be more time-efficient and further utilize C#'s asynchrony.&lt;/p&gt;

&lt;p&gt;See you soon. 👋&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
