<?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>DEV Community: Damiaan</title>
    <description>The latest articles on DEV Community by Damiaan (@dampee).</description>
    <link>https://dev.to/dampee</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%2F183724%2Fdcaeba6e-ee8f-40f9-b10d-292660c45e8a.jpg</url>
      <title>DEV Community: Damiaan</title>
      <link>https://dev.to/dampee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dampee"/>
    <language>en</language>
    <item>
      <title>Looking at c#'s Task&lt;IEnumerable&lt;T&gt;&gt;</title>
      <dc:creator>Damiaan</dc:creator>
      <pubDate>Mon, 26 May 2025 13:56:30 +0000</pubDate>
      <link>https://dev.to/dampee/looking-at-cs-taskienumerable-14ph</link>
      <guid>https://dev.to/dampee/looking-at-cs-taskienumerable-14ph</guid>
      <description>&lt;p&gt;On the surface, &lt;code&gt;Task&amp;lt;IEnumerable&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt; looks harmless — you're just asynchronously returning a list of things. But under the hood, there's a mismatch between what the caller sees and what the code actually does.&lt;/p&gt;

&lt;p&gt;Let’s unpack it.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; is Lazy by Design
&lt;/h2&gt;

&lt;p&gt;The IEnumerable interface represents a deferred execution model. It doesn’t hold data — it describes a computation that yields data when enumerated.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;IEnumerable&amp;lt;int&amp;gt; GetNumbers()&lt;br&gt;
{&lt;br&gt;
    yield return 1;&lt;br&gt;
    yield return 2;&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here, &lt;code&gt;GetNumbers()&lt;/code&gt; doesn’t do anything until the caller starts iterating. It’s not a collection — it’s a generator.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. &lt;code&gt;Task&amp;lt;IEnumerable&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt; Suggests Lazy + Async — But It’s Not
&lt;/h2&gt;

&lt;p&gt;Let’s say you write:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;public async Task&amp;lt;IEnumerable&amp;lt;User&amp;gt;&amp;gt; GetUsersAsync()&lt;br&gt;
{&lt;br&gt;
    return await _context.Users.ToListAsync();&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You're returning a fully materialized list, but your method signature doesn’t say that. To the caller, this looks like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I'm going to give you a lazily-evaluated collection — once the async operation is done."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is misleading because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The data is already in memory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; can be enumerated multiple times, each of which may repeat logic or side effects.&lt;/li&gt;
&lt;li&gt;But here, re-enumerating just re-reads the in-memory list — not re-executes anything — and that behavior is hidden.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Async Methods use State Machines — But not for IEnumerable
&lt;/h2&gt;

&lt;p&gt;When you await in a method, the compiler rewrites it into a state machine — tracking the position across awaits. However:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This async state machine wraps only the &lt;strong&gt;outer method body&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;It &lt;strong&gt;doesn’t know&lt;/strong&gt; how or when the returned &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; will be used.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So if a developer thinks this is a streaming or delayed-fetch API — because &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; can be — they're wrong. It’s just a preloaded list.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The Real Danger: Confusion and Redundant Work
&lt;/h2&gt;

&lt;p&gt;Because the return type hides the fact that the data is already materialized, consumers often:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var users = (await repo.GetUsersAsync()).ToList(); // unnecessary!&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This results in a copy of a list that's already a list.&lt;/p&gt;

&lt;p&gt;Worse, if the internal repo implementation is ever refactored to yield from a generator, the caller’s .ToList() could re-execute database queries (in a non-buffered scenario).&lt;/p&gt;

&lt;h2&gt;
  
  
  Clearer Alternatives
&lt;/h2&gt;

&lt;p&gt;To avoid these issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Return &lt;code&gt;IReadOnlyList&amp;lt;T&amp;gt;&lt;/code&gt; to make it explicit that the result is fully realized.&lt;/li&gt;
&lt;li&gt;Return &lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; if you want streaming, lazy loading, or pipelining behavior.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>csharp</category>
    </item>
    <item>
      <title>Awaiting the Task.CompletedTask?</title>
      <dc:creator>Damiaan</dc:creator>
      <pubDate>Mon, 26 May 2025 13:55:31 +0000</pubDate>
      <link>https://dev.to/dampee/awaiting-the-taskcompletedtask-34j7</link>
      <guid>https://dev.to/dampee/awaiting-the-taskcompletedtask-34j7</guid>
      <description>&lt;p&gt;After I saw a colleague struggling with Task.CompletedTask, I thought I might be worth sharing our learning.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Task.CompletedTask?
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.completedtask?view=net-8.0" rel="noopener noreferrer"&gt;Task.CompletedTask&lt;/a&gt; is a property on the Task class that returns a task that has already completed successfully, as the Status property will contain RanToCompletion.&lt;/p&gt;

&lt;p&gt;In a sense, Task.CompletedTask is conceptually similar to Task.FromResult but for void returns. Both are used to create tasks that are done executing. One returns a value, the other doesn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use Task.Completed
&lt;/h2&gt;

&lt;p&gt;It's useful when you have a &lt;strong&gt;Task return type&lt;/strong&gt; in a method and you need to return &lt;strong&gt;without actually doing any asynchronous work&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consider using the 'await' operator
&lt;/h2&gt;

&lt;p&gt;My best guess is you have warning CS1998&lt;br&gt;
Let's see what it says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is where programmers think they need to follow the advice from the warning. And they are trying to add more stuff to the solution trying to resolve the issue. When they come up with &lt;code&gt;await Task.CompletedTask;&lt;/code&gt; the warning will disappear. &lt;/p&gt;
&lt;h2&gt;
  
  
  Is adding await Task.CompletedTask the right solution?
&lt;/h2&gt;

&lt;p&gt;Let's take a step back.&lt;/p&gt;

&lt;p&gt;Having an &lt;code&gt;async&lt;/code&gt;method will add a state machine to your method. This will involve a slight (unnoticably) overhead. &lt;/p&gt;

&lt;p&gt;Here is a c# 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="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;M&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="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;When compilation is done, there will be a new method in your class trying to handle any await.&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;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;MoveNext&lt;/span&gt;&lt;span class="p"&gt;()&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;num&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt; &lt;span class="p"&gt;=&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="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;t__builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt; &lt;span class="p"&gt;=&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="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;t__builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetResult&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;Replacing the return with &lt;code&gt;await Task.CompletedTask&lt;/code&gt; converts the MoveNext() generated method to a beast.&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;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;MoveNext&lt;/span&gt;&lt;span class="p"&gt;()&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;num&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;TaskAwaiter&lt;/span&gt; &lt;span class="n"&gt;awaiter&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;num&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="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;awaiter&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;CompletedTask&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;awaiter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsCompleted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&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="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;u__1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;awaiter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d__0&lt;/span&gt; &lt;span class="n"&gt;stateMachine&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                        &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;t__builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AwaitUnsafeOnCompleted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;awaiter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;stateMachine&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="k"&gt;return&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;else&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;awaiter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;u__1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;u__1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TaskAwaiter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt; &lt;span class="p"&gt;=&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="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;awaiter&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;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt; &lt;span class="p"&gt;=&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="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;t__builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt; &lt;span class="p"&gt;=&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="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;t__builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetResult&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;Look at 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="n"&gt;awaiter&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;CompletedTask&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;awaiter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsCompleted&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We already learned that the Task.CompletedTask is a property that is already completed. So the compiler will be checking for completion of something that is already completed.&lt;/p&gt;

&lt;p&gt;So adding in the await Task.Completed task is adding unnecessary asynchronous overhead.&lt;br&gt;
Although the performance hit might be minimal, it's still an unnecessary context switch and state machine generation, which could be avoided.&lt;/p&gt;

&lt;p&gt;On top of that it can be misleading to other developers reading your code. Seeing await typically suggests there is an asynchronous operation occurring, but in this case, it does not. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to resolve warning CS1998
&lt;/h2&gt;

&lt;p&gt;If there's no actual asynchronous work, consider &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;removing the async and &lt;/li&gt;
&lt;li&gt;returning a completed task directly without await:
&lt;/li&gt;
&lt;/ol&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="nf"&gt;SomeMethod&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 code here...&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="n"&gt;CompletedTask&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;This avoids the overhead associated with async and await and is more efficient and clear.&lt;/p&gt;

&lt;p&gt;While await Task.CompletedTask; is not inherently "bad", it's unnecessary and can be avoided. It's typically better to return Task.CompletedTask directly when no asynchronous operation is required. &lt;/p&gt;

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