{"id":3031,"date":"2022-02-23T17:09:48","date_gmt":"2022-02-23T09:09:48","guid":{"rendered":"https:\/\/www.develop-note.com\/blog\/?p=3031"},"modified":"2022-02-23T17:09:48","modified_gmt":"2022-02-23T09:09:48","slug":"asp-net-core-asynchronous-programming","status":"publish","type":"post","link":"https:\/\/www.develop-note.com\/blog\/en\/2022\/02\/23\/asp-net-core-asynchronous-programming\/","title":{"rendered":"Asp.Net Core Asynchronous programming"},"content":{"rendered":"<p>Recently, I encountered an asynchronous problem when writing the APIs of Asp.Net Core, and I really felt unexpected after solving it, so I wrote it down and shared it with you, and avoid encountering it later.<\/p>\n<p><!--more--><\/p>\n<h2>What is Asynchronous<\/h2>\n<p>Before explaining what is asynchronous, let everyone know what the definition of synchronization is, simply put, a task is done continuously, and the next task will not be done before the previous task is done, as shown in the following figure.<\/p>\n<pre><code class=\"language-mermaid\">flowchart LR\nA(TASK A) --&gt; B(TASK B)--&gt;C(TASK C) --&gt; D(TASK D) --&gt; E(TASK E)<\/code><\/pre>\n<p>As for async, it is possible to have multiple tasks at the same time, and there is no need to wait because the simultaneous tasks have not yet completed, as shown in the following figure.<\/p>\n<pre><code class=\"language-mermaid\">flowchart LR\nA(TASK A) --&gt; B(TASK B)\nC(TASK C) --&gt; D(TASK D) --&gt; E(TASK E)\nF(TASK F) --&gt; G(TASK G)<\/code><\/pre>\n<h2>So what programming I happen<\/h2>\n<p>The problem is that when a highly concurrent request is encountered, the APIs are timed out to respond to the request.<br \/>\nAfter some modifications and cross-comparisons, it was found that the synchronized writing API encountered the need to communicate with other APIs, and if it was high concurrency, it would cause our APIs to no longer respond.<br \/>\nThen there is the fact that when the asynchronous writing is wrong, it will also cause a serious timeout condition, so I will explain it further.<\/p>\n<h3>Asp.Net Core Asynchronous<\/h3>\n<p>After the <code>.Net Framework 4.5<\/code> there is more <code>async<\/code> and <code>await<\/code> keyword, just declare <code>async<\/code> before you want to pass back the value as an asynchronous method and with <code>Task&lt;T&gt;<\/code> to complete the asynchronous method, then use <code>await<\/code> before calling the method to synchronously wait for the result, and do not add the <code>await<\/code> keyword if you do not need to wait. The complete example is as follows.<\/p>\n<pre><code class=\"language-csharp\">    public async Task&lt;IEnumerable&lt;string&gt;&gt; GetStringAsync()\n    {\n        await Task.Delay(TimeSpan.FromSeconds(10));\n        return new string[]{&quot;First&quot;, &quot;Second&quot;, &quot;Third&quot;};\n    }<\/code><\/pre>\n<h3>Problem I have<\/h3>\n<p>If you write before from the <code>.Net Framework 4.5<\/code>, and need the synchronous syntax to high concurrency requests or complex operations or communicate with other APIs. Then the synchronous API cannot use the <code>await<\/code> keyword when calling to the asynchronous syntax, so it can only use the <code>Task.Result<\/code> method to call, as shown in the following figure.<\/p>\n<pre><code class=\"language-cs\">    [HttpGet(&quot;Result&quot;)]\n    public IEnumerable&lt;string&gt; GetResult()\n    {\n        return _service.GetStringAsync().Result;\n    }<\/code><\/pre>\n<p>However, the synchronous syntax encounters a high concurrency request will cause a response timeout situation, so the asynchronous syntax will be used to rewrite, but simply adding <code>async<\/code> and work with <code>Task.Result<\/code> will still cause a blocking situation, which is crawling to see <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/csharp\/async\" title=\"Asynchronous programming\" rel=\"nofollow noopener\" target=\"_blank\">MSDN asynchronous programming<\/a> to know that there is such a result, so the following writing method will still cause the request to block the situation.<\/p>\n<pre><code class=\"language-cs\">    [HttpGet(&quot;Result&quot;)]\n    public async Task&lt;IEnumerable&lt;string&gt;&gt; GetResult()\n    {\n        return _service.GetStringAsync().Result;\n    }<\/code><\/pre>\n<p>So how to write is the right way to write?<\/p>\n<h3>Correct writing<\/h3>\n<p>So in summary, to write an asynchronous API, you basically need to use the keyword <code>async<\/code> first, and then use the return value of <code>Task&lt;T&gt;<\/code> or <code>Task<\/code> for whether there is a callback value or no need return value, as shown below.<\/p>\n<pre><code class=\"language-cs\">    [HttpGet(&quot;String&quot;)]\n    public async Task&lt;IEnumerable&lt;string&gt;&gt; GetString()\n    {\n        await Task.Delay(TimeSpan.FromSeconds(10));\n        return new string[]{&quot;First&quot;, &quot;Second&quot;, &quot;Third&quot;};\n    }<\/code><\/pre>\n<p>In addition, when encountering a method that needs to be blocked, that is, when encountering a method that needs to wait for the result of another method, use the keyword <code>await<\/code>, as shown below,<\/p>\n<pre><code class=\"language-cs\">    [HttpGet(&quot;Result&quot;)]\n    public async Task&lt;IEnumerable&lt;string&gt;&gt; GetResult()\n    {\n        return await _service.GetStringAsync();\n    }<\/code><\/pre>\n<p>Be careful not to use a way of writing <code>Task.Result<\/code> here, otherwise the reaction time of the run will be greatly reduced.<\/p>\n<h3>Result<\/h3>\n<p>Whether it&#8217;s written synchronously or in the asynchronous API call <code>Task.Result<\/code>, the result when a highly concurrent call of 100 times per second is encountered will react with a delay of more than five seconds, and only the <code>async\/await<\/code> can react normally within three seconds.<\/p>\n<h2>Conclusion<\/h2>\n<p>After this experience, when writing APIs, first write <code>async<\/code>, so as to avoid the dilemma that the api&#8217;s reaction is blocked when high concurrency is blocked. Then the asynchronous&#8217; writing method must be written with <code>aync<\/code> and <code>await<\/code>, avoiding the writing of <code>Task.Result<\/code>, so as to avoid the occurrence of blocking.<\/p>\n<h2>Reference<\/h2>\n<ol>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/csharp\/async\" title=\"Asynchronous programming\" rel=\"nofollow noopener\" target=\"_blank\">MSDN Asynchronous programming<\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Recently, I encountered an asynchronous problem when wr &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.develop-note.com\/blog\/en\/2022\/02\/23\/asp-net-core-asynchronous-programming\/\" class=\"more-link\">\u95b1\u8b80\u5168\u6587<span class=\"screen-reader-text\">\u3008Asp.Net Core Asynchronous programming\u3009<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[168],"tags":[179,173],"class_list":["post-3031","post","type-post","status-publish","format-standard","hentry","category-develop-en","tag-async-en","tag-dotnetcore-en"],"_links":{"self":[{"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/posts\/3031","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/comments?post=3031"}],"version-history":[{"count":11,"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/posts\/3031\/revisions"}],"predecessor-version":[{"id":3042,"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/posts\/3031\/revisions\/3042"}],"wp:attachment":[{"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/media?parent=3031"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/categories?post=3031"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/tags?post=3031"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}