<?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: Joni 【ジョニー】</title>
    <description>The latest articles on DEV Community by Joni 【ジョニー】 (@joni2nja).</description>
    <link>https://dev.to/joni2nja</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%2F167215%2Fc733fdc1-50e2-4427-965e-180477fbb79a.jpg</url>
      <title>DEV Community: Joni 【ジョニー】</title>
      <link>https://dev.to/joni2nja</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joni2nja"/>
    <language>en</language>
    <item>
      <title>Visual Guide to C# async/await</title>
      <dc:creator>Joni 【ジョニー】</dc:creator>
      <pubDate>Sun, 04 Jul 2021 22:02:27 +0000</pubDate>
      <link>https://dev.to/joni2nja/visual-guide-to-c-async-await-54ha</link>
      <guid>https://dev.to/joni2nja/visual-guide-to-c-async-await-54ha</guid>
      <description>&lt;p&gt;Microsoft first introduced &lt;code&gt;async/await&lt;/code&gt; pattern in C# 5.0 back in 2011. I think it’s one of the greatest contributions to the asynchronous programming — at languages level— which led other programming languages to follow, like Python and JavaScript, to name a few. It makes asynchronous code more readable, more like the ordinary synchronous code. Remember those old-school &lt;code&gt;BeginXxx&lt;/code&gt; / &lt;code&gt;EndXxx&lt;/code&gt; in &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/asynchronous-programming-model-apm"&gt;&lt;em&gt;Asynchronous Programming Model/APM&lt;/em&gt;&lt;/a&gt; in C# 1.0? I can still remember writing those in 2002 with Visual Studio .NET 2002.&lt;/p&gt;

&lt;p&gt;Enough foreword. Do you still remember the famous “&lt;a href="https://blog.stephencleary.com/2013/11/there-is-no-thread.html"&gt;There Is No Thread&lt;/a&gt;” post from Stephen Cleary?&lt;/p&gt;

&lt;p&gt;If you’re newbie to C#, go read it. I will wait. Perhaps, I should say &lt;code&gt;await ReadAsync()&lt;/code&gt; ?😆&lt;/p&gt;

&lt;p&gt;Okay, I’m glad you’re still here. This post is my attempt to help C# developers to better grasp what async/await is all about.&lt;/p&gt;

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

&lt;p&gt;Let’s start with the synchronous version.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rldD4Bfs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/700/1%2A36pNjD8qAjiUhkyidq-Z7Q.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rldD4Bfs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/700/1%2A36pNjD8qAjiUhkyidq-Z7Q.gif" alt="Visualized: Ordinary, synchronous method call in C#"&gt;&lt;/a&gt;Visualized: Ordinary, synchronous method call in C#&lt;/p&gt;

&lt;p&gt;Nothing fancy here. I guess it’s pretty straightforward and self-explanatory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Asynchronous code
&lt;/h3&gt;

&lt;p&gt;Next, the asynchronous one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8lnvH8qA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/700/1%2AJUlC43DA7pMGtaRt2Sg_eg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8lnvH8qA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/700/1%2AJUlC43DA7pMGtaRt2Sg_eg.gif" alt="Visualized: Asynchronous method call in C#"&gt;&lt;/a&gt;Visualized: Asynchronous method call in C#&lt;/p&gt;

&lt;p&gt;As you can see, our asynchronous chef put &lt;code&gt;await MethodAsync()&lt;/code&gt; in the kitchen and then leaves the kitchen without waiting for the 🍜(Task&amp;lt;🍜&amp;gt;) to be ready. Our synchronous chef, whereas, in contrast, will be hanging around, perhaps forever in the kitchen, waiting for the 🍜.&lt;/p&gt;

&lt;p&gt;Our asynchronous chef leaves the kitchen, returns to his &lt;strong&gt;&lt;em&gt;home&lt;/em&gt;&lt;/strong&gt; (thread &lt;strong&gt;&lt;em&gt;pool&lt;/em&gt;&lt;/strong&gt; ), waiting with his lovely &lt;strong&gt;&lt;em&gt;family members&lt;/em&gt;&lt;/strong&gt; (thread pool &lt;strong&gt;&lt;em&gt;threads&lt;/em&gt;&lt;/strong&gt; ) while keeping the door open (assuming &lt;code&gt;ConfigureAwait(false)&lt;/code&gt;; trying to simulate “no &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.synchronizationcontext"&gt;Synchronization Context&lt;/a&gt;” here). At this point, we are in the so-called “there is no thread” state. Nobody is in the kitchen. Our 🍜 is still sitting in the microwave (ongoing I/O operation). &lt;em&gt;Sorry to disappoint you, my dear reader, it’s instant noodles&lt;/em&gt; 😂.&lt;/p&gt;

&lt;p&gt;Once it’s heated, our super smart AI-powered-alarm-shaped drone (I/O Completion Port — IOCP) flies to our chef’s house to notify them. Remember that the door is left open (again, no &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.synchronizationcontext"&gt;Synchronization Context&lt;/a&gt;), but our chef is in the toilet 🚽, so he asked his wife — who happened to be a chef as well — to go to continue his work. She resumes her husband’s remaining tasks, picks where her husband left it off (resuming &lt;code&gt;AsyncStateMachine&lt;/code&gt;). The rest is the same as the synchronous version.&lt;/p&gt;

&lt;h3&gt;
  
  
  Visualize using Visual Studio
&lt;/h3&gt;

&lt;p&gt;The animated GIFs are there to illustrate analogies in the our-almost-real-world. Let’s try to visualize it using Visual Studio.&lt;/p&gt;

&lt;p&gt;We’ll be using the following code, a &lt;a href="https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-6-preview-4/#introducing-minimal-apis"&gt;minimal APIs&lt;/a&gt;, new in .NET 6.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var builder = WebApplication.CreateBuilder(args);
await using var app = builder.Build();

if (app.Environment.IsDevelopment())
{
  app.UseDeveloperExceptionPage();
}

app.MapGet("/sleep", (CancellationToken cancellationToken) =&amp;gt;
{
  while (!cancellationToken.IsCancellationRequested)
  {
    Enumerable.Range(1, 100).Select(x =&amp;gt; x).ToList().ForEach(x =&amp;gt;
    {
      //WARNING: BAD CODE
      Task.Run(() =&amp;gt; Thread.Sleep(3 * 60 * 1_000), cancellationToken);
    });
    Thread.Sleep(2 * 60 * 1_000);
  }
  return "Done.";
});

app.MapGet("/delay", async (CancellationToken cancellationToken) =&amp;gt;
{
  while (!cancellationToken.IsCancellationRequested)
  {
    Enumerable.Range(1, 100).Select(x =&amp;gt; x).ToList().ForEach(x =&amp;gt;
    {
      //WARNING: BAD CODE
      Task.Run(async () =&amp;gt; await Task.Delay(3 * 60 * 1_000, cancellationToken), cancellationToken);
    });
    await Task.Delay(2 * 60 * 1_000, cancellationToken);
  }
  return "Done.";
});

await app.RunAsync();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;First, we will inspect the synchronous version. Go to &lt;em&gt;&lt;a href="https://localhost:5001/sleep"&gt;https://localhost:5001/sleep&lt;/a&gt;&lt;/em&gt;. Inspect the process using &lt;a href="https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer"&gt;Process Explorer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m8oriEFf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/839/1%2Af513CGWiuYjqzDPP_SwmvQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m8oriEFf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/839/1%2Af513CGWiuYjqzDPP_SwmvQ.png" alt="Inspect using Process Explorer"&gt;&lt;/a&gt;Inspect using Process Explorer&lt;/p&gt;

&lt;p&gt;We can see that we are starting up &lt;strong&gt;100 threads&lt;/strong&gt;. Notice the scrollbar? We have a bunch of threads hanging around.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;📝&lt;/em&gt; Even though we are calling &lt;code&gt;Thread.Sleep&lt;/code&gt;, it’s still a waste of resources.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s go back to Visual Studio, use &lt;strong&gt;Break All&lt;/strong&gt; to pause the application execution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tU_rEE7F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/551/1%2AGtN_HrYHeJE48E_RpzGvLg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tU_rEE7F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/551/1%2AGtN_HrYHeJE48E_RpzGvLg.png" alt="Break All in Visual Studio"&gt;&lt;/a&gt;Break All in Visual Studio&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;📝&lt;/em&gt; You can use &lt;code&gt;Debugger.Break&lt;/code&gt; to achieve the same effect. Details: &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.debugger.break"&gt;https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.debugger.break&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Look at the &lt;strong&gt;Parallel Stacks&lt;/strong&gt;  window.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QQSlrW6E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AGKDJa4Pxf9-G-MmLnLwMXg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QQSlrW6E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AGKDJa4Pxf9-G-MmLnLwMXg.png" alt="Parallel Stacks window"&gt;&lt;/a&gt;Parallel Stacks window&lt;/p&gt;

&lt;p&gt;A lot of sleeping threads are in “blocked” state. It’s like our synchronous chef in the kitchen doing nothing except &lt;em&gt;waiting&lt;/em&gt; for the 🍜 to be heated in the microwave.&lt;/p&gt;

&lt;p&gt;Now, switch the &lt;strong&gt;View&lt;/strong&gt; to &lt;strong&gt;Threads&lt;/strong&gt; view to see how it looks, grouped by threads. Hundreds of threads!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7HXegBPh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/775/1%2A7WRfuChV1IAaDgGf42rpPg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7HXegBPh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/775/1%2A7WRfuChV1IAaDgGf42rpPg.png" alt="View by Threads."&gt;&lt;/a&gt;View by Threads.&lt;/p&gt;

&lt;p&gt;Let’s see &lt;strong&gt;Threads&lt;/strong&gt; window. Notice the scrollbar?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6RVf-fOK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AmUajcQvatkDFqzZ4-srh5Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6RVf-fOK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AmUajcQvatkDFqzZ4-srh5Q.png" alt="Threads window"&gt;&lt;/a&gt;Threads window&lt;/p&gt;

&lt;h3&gt;
  
  
  Asynchronous code
&lt;/h3&gt;

&lt;p&gt;Next, let’s see asynchronous version. Go to &lt;em&gt;&lt;a href="https://localhost:5001/delay"&gt;https://localhost:5001/delay&lt;/a&gt;&lt;/em&gt;. Inspect the process using &lt;a href="https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer"&gt;Process Explorer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GKGaZPVY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/841/1%2AVoliFRL3PX6NEyRpHZokOQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GKGaZPVY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/841/1%2AVoliFRL3PX6NEyRpHZokOQ.png" alt="Inspect using Process Explorer"&gt;&lt;/a&gt;Inspect using Process Explorer&lt;/p&gt;

&lt;p&gt;We have started 100 tasks, but hey, there is no scrollbar!&lt;/p&gt;

&lt;p&gt;Go back to Visual Studio, pause the application execution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tU_rEE7F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/551/1%2AGtN_HrYHeJE48E_RpzGvLg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tU_rEE7F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/551/1%2AGtN_HrYHeJE48E_RpzGvLg.png" alt="Break All in Visual Studio"&gt;&lt;/a&gt;Break All in Visual Studio&lt;/p&gt;

&lt;p&gt;Look at the &lt;strong&gt;Parallel Stacks&lt;/strong&gt;  window.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Re4cHOuQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AMhgVpD6T9vJ8ss-wfohXPw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Re4cHOuQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AMhgVpD6T9vJ8ss-wfohXPw.png" alt="Parallel Stacks window. A bunch of tasks are in “scheduled” state."&gt;&lt;/a&gt;Parallel Stacks window. A bunch of tasks are in “scheduled” state.&lt;/p&gt;

&lt;p&gt;Lots of &lt;em&gt;tasks&lt;/em&gt; are in a “scheduled” state; scheduled to be fired in the future. In &lt;strong&gt;Thread&lt;/strong&gt; column, you can see that &lt;strong&gt;there is no thread info, no thread ID&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Did you just scroll up to double-check the screenshot of the synchronous version? Welcome back! 😆&lt;/p&gt;

&lt;p&gt;Now, switch the &lt;strong&gt;View&lt;/strong&gt; to &lt;strong&gt;Threads&lt;/strong&gt; view to see how it looks, grouped by threads.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sCsV-jEi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/928/1%2Aa8GVw2Dzsjs68_DwWqqhEg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sCsV-jEi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/928/1%2Aa8GVw2Dzsjs68_DwWqqhEg.png" alt="View by Threads."&gt;&lt;/a&gt;View by Threads.&lt;/p&gt;

&lt;p&gt;Less than ten threads, that’s mostly the framework threads.&lt;/p&gt;

&lt;p&gt;Let’s see &lt;strong&gt;Threads&lt;/strong&gt; window. Notice that there is no scrollbar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nRv4vZLt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AJi0Yk4aOeclAJIXiusefGw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nRv4vZLt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AJi0Yk4aOeclAJIXiusefGw.png" alt="Threads window"&gt;&lt;/a&gt;Threads window&lt;/p&gt;

&lt;p&gt;So yes, there is &lt;strong&gt;“no thread”&lt;/strong&gt; here. No user code thread, to be precise. No thread, no chef. Like our asynchronous chef, instead of waiting in the kitchen, he returns to his home sweet home.&lt;/p&gt;

&lt;p&gt;That’s it!&lt;/p&gt;

&lt;p&gt;So what does this mean? For ASP.NET, this “ &lt;strong&gt;no thread”&lt;/strong&gt; will translate to a &lt;strong&gt;scalability improvement&lt;/strong&gt; since we don’t block our precious thread pool threads; blocking might lead to thread pool starvation. Here is the analogy. We only have five chefs. All of them are now waiting in the kitchen, doing nothing. We can no longer process additional cooking orders. But if they don’t simply wait in the kitchen, they would be able to process the same amount of orders with, say, just only two chefs. Given that two busy chefs in the kitchen, we still have three remaining chefs idle, waiting for the new additional cooking orders.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>asynchronous</category>
      <category>async</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>VS Code の Remote Repositories はいいぞ。その他の便利なツールを比較してみた。</title>
      <dc:creator>Joni 【ジョニー】</dc:creator>
      <pubDate>Mon, 14 Jun 2021 16:19:23 +0000</pubDate>
      <link>https://dev.to/joni2nja/vs-code-remote-repositories-goa</link>
      <guid>https://dev.to/joni2nja/vs-code-remote-repositories-goa</guid>
      <description>&lt;p&gt;VS Code version 1.57 で &lt;a href="https://code.visualstudio.com/updates/v1_57#_remote-repositories"&gt;Remote Repositories&lt;/a&gt; の拡張機能をインストールすることで、 GitHub 上のリポジトリをローカルにクローンしなくても、コードの参照はもちろん、検索と更新（プッシュ）もシームレスに可能になりました。  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;実は &lt;a href="https://code.visualstudio.com/updates/v1_56#_remote-repositories-remotehub"&gt;VS Code Insiders&lt;/a&gt; で最初に使えた機能で、それでしばらく使っていました。 Stable に早くも使えるなんて嬉しいですね。 Insiders でドラフトで途中で修正していたものがあって、Stable がリリースしたタイミングで、同時に更新してみたら、ドラフトが全部消えたという悲しいことがありましたが、まあ大した内容ではありませんし、 Insiders ですし、文句は言えません。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;使い方は Insiders リリース時のとあまり変わらないのですが、操作イメージは&lt;a href="https://www.youtube.com/watch?v=wHsmaXoGIXI"&gt;動画&lt;/a&gt;を見た方が分かりやすいかと思います。&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/wHsmaXoGIXI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;また、公式&lt;a href="https://code.visualstudio.com/blogs/2021/06/10/remote-repositories"&gt;ブログ&lt;/a&gt;にも詳細情報がありますので、使えない機能等の注意点も併せて参照してみてください。&lt;/p&gt;

&lt;p&gt;これまでは別のツールを使ってきましたが、下記で紹介したいと思います。&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub を活用する便利なツール
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Octotree
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.octotree.io/"&gt;https://www.octotree.io/&lt;/a&gt;&lt;br&gt;
恐らく定番の中の定番でしょうか。ブラウザの拡張機能で、ディレクトリをツリー表示で参照がかなり楽になります。&lt;/p&gt;
&lt;h3&gt;
  
  
  github1s
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/conwnet/github1s"&gt;https://github.com/conwnet/github1s&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/conwnet"&gt;
        conwnet
      &lt;/a&gt; / &lt;a href="https://github.com/conwnet/github1s"&gt;
        github1s
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      One second to read GitHub code with VS Code.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://raw.githubusercontent.com/conwnet/github1s/master/resources/images/logo.svg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P3JigqDY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/conwnet/github1s/master/resources/images/logo.svg" alt="GitHub1s"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
github1s&lt;/h1&gt;
&lt;p&gt;One second to read GitHub code with VS Code.&lt;/p&gt;
&lt;h2&gt;
Usage&lt;/h2&gt;
&lt;p&gt;Just add &lt;code&gt;1s&lt;/code&gt; after &lt;code&gt;github&lt;/code&gt; and press &lt;code&gt;Enter&lt;/code&gt; in the browser address bar for any repository you want to read.&lt;/p&gt;
&lt;p&gt;For example, try it on the VS Code repo:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github1s.com/microsoft/vscode" rel="nofollow"&gt;https://github1s.com/microsoft/vscode&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://raw.githubusercontent.com/conwnet/github1s/master/resources/images/vs-code-github1s.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LVhjmGPo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/conwnet/github1s/master/resources/images/vs-code-github1s.png" alt="VS Code - GitHub1s"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For browser extensions, see &lt;a href="https://github.com/conwnet/github1s#third-party-related-projects"&gt;Third-party Related Projects&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Or save the following code snippet as a bookmarklet, you can use it to quickly switch between github.com and github1s.com (GitHub markdown doesn't allow js links, so just copy it into a bookmark).&lt;/p&gt;
&lt;div class="snippet-clipboard-content position-relative"&gt;&lt;pre&gt;&lt;code&gt;javascript: window.location.href = window.location.href.replace(/github(1s)?.com/, function(match, p1) { return p1 ? 'github.com' : 'github1s.com' })
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;
Develop in the cloud&lt;/h3&gt;
&lt;p&gt;To edit files, run Docker containers, create pull requests and more, click the "Develop your project on &lt;a href="https://www.gitpod.io" rel="nofollow"&gt;Gitpod&lt;/a&gt;" button in the status bar. You can also open the Command Palette (default shortcut &lt;code&gt;Ctrl+Shift+P&lt;/code&gt;) and choose &lt;code&gt;GitHub1s: Edit files in Gitpod&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://raw.githubusercontent.com/conwnet/github1s/master/resources/images/gitpod-statusbar.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PDoyhBIi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/conwnet/github1s/master/resources/images/gitpod-statusbar.png" alt="Gitpod Status Bar"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
Documentation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/conwnet/github1s/blob/master/docs/guide.md"&gt;How it works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/conwnet/github1s/projects/1"&gt;Roadmap&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Enabling Private&lt;/h2&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/conwnet/github1s"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
URLのところの &lt;code&gt;github&lt;/code&gt; の後に &lt;code&gt;1s&lt;/code&gt; をつけて &lt;code&gt;ENTER&lt;/code&gt; キー押下で VS Code（のUI）がブラウザ上で表示されちゃいます！&lt;br&gt;
例： &lt;br&gt;
&lt;a href="https://github.com/facebook/react"&gt;https://github.com/facebook/react&lt;/a&gt;&lt;br&gt;
↓↓↓&lt;br&gt;
&lt;a href="https://github1s.com/facebook/react"&gt;https://github1s.com/facebook/react&lt;/a&gt;
&lt;h3&gt;
  
  
  Gitpod
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.gitpod.io/"&gt;https://www.gitpod.io/&lt;/a&gt;&lt;br&gt;
ローカルへ Clone せず、クラウド上でクローンを行い、ファイルを GitHub 上で直接修正が可能。&lt;br&gt;
過去に .NET Core のリポジトリへプルリクエストを送信したことがあって、これで試してみました。&lt;br&gt;
&lt;/p&gt;
&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KUuQIgmh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/DmbVpS0VAAAsK_e.jpg" alt="unknown tweet media content"&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--ptLsO6y8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1004423178523774977/FbhWA9xc_normal.jpg" alt="Joni ✨ ジョニー 🚀 profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Joni ✨ ジョニー 🚀
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="mentioned-user" href="https://dev.to/joni2nja"&gt;@joni2nja&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Trying commit + push &lt;a href="https://twitter.com/hashtag/aspnetcore"&gt;#aspnetcore&lt;/a&gt; MVC code from &lt;a href="https://twitter.com/hashtag/Gitpod"&gt;#Gitpod&lt;/a&gt;. 👍&lt;br&gt;&lt;br&gt;Gitpod ちょっと試してみた。良さそうやね。 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      17:21 PM - 06 Sep 2018
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1037752547895701504" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1037752547895701504" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1037752547895701504" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;



&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--ptLsO6y8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1004423178523774977/FbhWA9xc_normal.jpg" alt="Joni ✨ ジョニー 🚀 profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Joni ✨ ジョニー 🚀
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="mentioned-user" href="https://dev.to/joni2nja"&gt;@joni2nja&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      VS Code Remote - Containers &lt;a href="https://twitter.com/hashtag/dotnetcore"&gt;#dotnetcore&lt;/a&gt; サンプル &lt;a href="https://t.co/RtiXadSFab"&gt;github.com/Microsoft/vsco…&lt;/a&gt; を見てみると、タイポ発見。PR送信後、もう１度読んでみると別のタイポに気づき、Gitpodでcommit追加しようとしたら、既にPRマージされた。マージ早っ！ &lt;a href="https://t.co/ygPG3q2PLa"&gt;twitter.com/code/status/11…&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      05:45 AM - 03 May 2019
    &lt;/div&gt;

      &lt;div class="ltag__twitter-tweet__quote"&gt;
        &lt;div class="ltag__twitter-tweet__quote__header"&gt;
          &lt;span class="ltag__twitter-tweet__quote__header__name"&gt;
            Visual Studio Code
          &lt;/span&gt;
          @code
        &lt;/div&gt;
        We can't contain our excitement. As of today, you can use a Docker container as your full-time development environment 🤯 🐳 📦

Using the Remote - Containers extension, you can open any folder inside (or mounted into) a container. #remote #containers 

👉 https://t.co/GO7YWNsFUH https://t.co/w5XieoHaSU
      &lt;/div&gt;

    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1124188189155942400" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1124188189155942400" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1124188189155942400" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;過去のクラウド上のクローンはダッシュボードで表示されるので、便利です。&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9DHVhhFv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a2s26oqpbc88qmx5o8vp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9DHVhhFv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a2s26oqpbc88qmx5o8vp.jpg" alt="gitpod01"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;修正・更新は VS Code みたいなので特に違和感ありませんでした。&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2TYkTvlI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/13uo046d0iia013asy9m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2TYkTvlI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/13uo046d0iia013asy9m.jpg" alt="gitpod02"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sourcegraph
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://about.sourcegraph.com/"&gt;https://about.sourcegraph.com/&lt;/a&gt;&lt;br&gt;
ブラウザ上でソースコードの検索を中心としたツールです。&lt;/p&gt;

&lt;h3&gt;
  
  
  Git History
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://githistory.xyz/"&gt;https://githistory.xyz/&lt;/a&gt;&lt;br&gt;
ソースコードの変更履歴・差分をアニメーションで表示してくれます。&lt;/p&gt;




&lt;h2&gt;
  
  
  まとめ
&lt;/h2&gt;

&lt;p&gt;上記の便利なツールで GitHub を使ってきましたが、用途によって使い分けが必要だと思います。 個人的は非常にシンプルな検索は GitHub 上で検索 + Octotree、あるいは github1s で済むことが多いのですが、今後より細かく検索・修正したい場合は VS Code で完結できる Remote Repositories を使う場面が多くなりそうです。簡単なプルリクエストを送信したい時もありますので、Remote Repositories で、「検索、一括置換、コミット」するだけで自動的にリモートリポジトリにプッシュされますので、プルリクエストを手軽に送れるようになるかと思います。是非試してみてはいかがでしょうか。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_ioyEUPj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ngq0jjq00gtpjnacig0f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_ioyEUPj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ngq0jjq00gtpjnacig0f.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>github</category>
      <category>git</category>
    </item>
    <item>
      <title>Use System.IO.Pipelines and System.Threading.Channels APIs to Boost Performance</title>
      <dc:creator>Joni 【ジョニー】</dc:creator>
      <pubDate>Sun, 20 Sep 2020 18:03:35 +0000</pubDate>
      <link>https://dev.to/joni2nja/use-system-io-pipelines-and-system-threading-channels-apis-to-boost-performance-2nj5</link>
      <guid>https://dev.to/joni2nja/use-system-io-pipelines-and-system-threading-channels-apis-to-boost-performance-2nj5</guid>
      <description>&lt;h4&gt;
  
  
  How to use System.IO.Pipelines and System.Threading.Channels APIs to speed up processing
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_kPixaaA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Ac1szTL0yaZwcsmLkcMcHRA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_kPixaaA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Ac1szTL0yaZwcsmLkcMcHRA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This post is kind of the continuation of my previous post series: &lt;a href="https://dev.to/joni2nja/evaluating-readline-using-system-io-pipelines-performance-in-c-part-2-pmf"&gt;&lt;strong&gt;Evaluating “ReadLine using System.IO.Pipelines” Performance in C#&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When I wrote those posts, I was in the need of processing a huge text file (hundreds of thousands of lines), read, parse and transform line by line, and then finally save each of them as a text file. Yes, it will end up a ton of files being created!&lt;/p&gt;

&lt;p&gt;I was able to speed up the reading time using System.IO.Pipelines APIs as described in the previous post. The result? 10 minutes faster processing time! 🚀&lt;/p&gt;

&lt;p&gt;I could have stopped there. But I didn’t. I recalled the new kids on the block: System.Threading.Channels. See Stephen Toub’s excellent post &lt;a href="https://devblogs.microsoft.com/dotnet/an-introduction-to-system-threading-channels/"&gt;“An Introduction to System.Threading.Channels”&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/dotnet/an-introduction-to-system-threading-channels/"&gt;An Introduction to System.Threading.Channels | .NET Blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Think of the reading line by line as the &lt;em&gt;Producer&lt;/em&gt; and the line processing part as &lt;em&gt;Consumer&lt;/em&gt;. The idea is, to produce as fast as possible using System.IO.Pipelines and consume it— spread the workload concurrently, &lt;em&gt;asynchronously&lt;/em&gt;, without blocking like BlockingCollection does.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;BlockingCollection involves blocking; there are no task-based APIs to perform work asynchronously. Channels is all about asynchrony; there are no synchronously-blocking APIs — Stephen Toub.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Okay, enough talking. Show me the code!&lt;/p&gt;

&lt;h3&gt;
  
  
  Base Implementation
&lt;/h3&gt;

&lt;p&gt;Let’s start from the base implementation (i.e., before using System.Threading.Channels APIs); the code is simply adding each line processing method to the Task list and await on all of them.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note that code on this post is slightly adjusted for benchmarks purpose; eliminating unrelated parts as much as possible.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We can see the task list growing as we process the line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ctvt7_oq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/739/1%2AvqRDgV3owQsxYIlGrxOP9A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ctvt7_oq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/739/1%2AvqRDgV3owQsxYIlGrxOP9A.png" alt=""&gt;&lt;/a&gt;Task list&lt;/p&gt;

&lt;h3&gt;
  
  
  Channel Writer (Producer)
&lt;/h3&gt;

&lt;p&gt;Here is the producer part.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;To help spot the changes quickly, here is the diff:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CmtVslTC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AXqKqYNIRkYBpZsijHz-6dg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CmtVslTC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AXqKqYNIRkYBpZsijHz-6dg.png" alt="Base implementation vs Channel implementation"&gt;&lt;/a&gt;Base implementation vs Channel implementation&lt;/p&gt;

&lt;p&gt;Should be pretty easy to spot the differences.&lt;/p&gt;

&lt;h3&gt;
  
  
  Channel Reader (Consumer)
&lt;/h3&gt;

&lt;p&gt;Finally, the consumer part.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Here I defined 3 channel readers and set SingleReader to false (by evaluating ChannelReaderCount == 1). This way, we will have 3 consumers that will process the line concurrently.&lt;/p&gt;

&lt;p&gt;This can be observed from the Visual Studio Parallel Stacks window.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gHDk_XtT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AWC0B2fsBGmeucKLnaPwzzg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gHDk_XtT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AWC0B2fsBGmeucKLnaPwzzg.png" alt=""&gt;&lt;/a&gt;Parallel Stacks Window&lt;/p&gt;

&lt;p&gt;Tune this value and measure until you get the best performance. Start small, increment the value until you reach to the point where it will give you slower results; it’s the point where you have too many active Task resources, possibly too many context switches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benchmarks Result
&lt;/h3&gt;

&lt;p&gt;Okay, let’s see the benchmarks result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2WLpcgXJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AtsJZld13exelfpVHGeXfQw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2WLpcgXJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AtsJZld13exelfpVHGeXfQw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Wow. Almost 2x faster! *&lt;/em&gt; 🚀🚀🚀&lt;/p&gt;

&lt;p&gt;Here is the gist version:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;That’s the benchmarks result. What about my case? Well, I saved another 10 minutes, so about 20 minutes faster in total!&lt;/p&gt;

&lt;h3&gt;
  
  
  Source Code
&lt;/h3&gt;

&lt;p&gt;You can find the source code in my &lt;a href="https://github.com/jo-ninja/ReadLinesBenchmarks"&gt;GitHub repository&lt;/a&gt;, branch: &lt;em&gt;pipelines-and-channels.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;If you have huge text files in size containing hundreds of thousands of lines to be processed, consider to use System.IO.Pipelines for reading and parsing the lines, and combine it with System.Threading.Channels APIs to spread the workload concurrently, asynchronously.&lt;/p&gt;

</description>
      <category>benchmark</category>
      <category>dotnet</category>
      <category>dotnetcore</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Evaluating “ReadLine using System.IO.Pipelines” Performance in C# — Part 2</title>
      <dc:creator>Joni 【ジョニー】</dc:creator>
      <pubDate>Mon, 17 Aug 2020 21:10:37 +0000</pubDate>
      <link>https://dev.to/joni2nja/evaluating-readline-using-system-io-pipelines-performance-in-c-part-2-pmf</link>
      <guid>https://dev.to/joni2nja/evaluating-readline-using-system-io-pipelines-performance-in-c-part-2-pmf</guid>
      <description>&lt;h3&gt;
  
  
  Evaluating “ReadLine using System.IO.Pipelines” Performance in C# — Part 2
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Read string line by line using System.IO.Pipelines API in C
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xM3eUw8R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AfzEzlMkFhQ11niqozD3DmA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xM3eUw8R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AfzEzlMkFhQ11niqozD3DmA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On &lt;a href="https://dev.to/joni2nja/evaluating-readline-using-system-io-pipelines-performance-in-c-2io8"&gt;part 1&lt;/a&gt; of this series, I concluded:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In terms of speed, it is surprisingly slower than the &lt;em&gt;ordinary&lt;/em&gt; ReadLine version given the string length ≤ 80 (perhaps I am doing it wrong? Let me know! I am still learning!). It is starting to shine, getting faster and faster if the string length ≥ 90. (270% 🚀 faster for string length = 1000).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I decided to take a further look and added more patterns to the benchmarks. The new code, instead of blindly using SequenceReader, is a mix of &lt;em&gt;fast&lt;/em&gt; ReadOnlySpan and &lt;em&gt;slow&lt;/em&gt; SequenceReader; by inspecting &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.buffers.readonlysequence-1.issinglesegment?view=netcore-3.1"&gt;ReadOnlySequence.IsSingleSegment&lt;/a&gt; property.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The idea is, &lt;em&gt;get a&lt;/em&gt; &lt;em&gt;Span once and then pull as many lines as possible out of it before moving to the next segment of the sequence&lt;/em&gt;, as also pointed out by a generous Reddit user &lt;em&gt;u/scalablecory&lt;/em&gt;, thanks! (apparently a member of the .NET Team?!)&lt;/p&gt;

&lt;p&gt;Here is the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CWmLKIkL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AwcZqGz5SFVPJ4OQnugMVqw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CWmLKIkL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AwcZqGz5SFVPJ4OQnugMVqw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  As you can see, it performs well under every test case, rendering my previous conclusion obsolete!!!
&lt;/h3&gt;

&lt;p&gt;And here is the gist version:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Noticed that this time it has fewer test cases; I reduced some LineCharMultiplier variations, as I don’t think we need it.&lt;/p&gt;

&lt;p&gt;You can find the source code in my &lt;a href="https://github.com/jo-ninja/ReadLinesBenchmarks"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Pipelines versions are better in terms of memory usage (using less memory).&lt;/li&gt;
&lt;li&gt;In terms of speed, it is 103% ~ 333% 🚀🚀🚀 faster, depends on the string length.&lt;/li&gt;
&lt;li&gt;Less GC pressure (a good thing) for Pipelines versions (Gen 0, Gen 1).&lt;/li&gt;
&lt;li&gt;The amount of code to write for the Pipelines version is super longer!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;DISCLAIMER: Your mileage may vary. As with all performance work, each of the scenarios chosen for your application should be measured, measured and measured. There is no silver bullet.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnetcore</category>
      <category>benchmark</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Evaluating “ReadLine using System.IO.Pipelines” Performance in C#</title>
      <dc:creator>Joni 【ジョニー】</dc:creator>
      <pubDate>Sun, 16 Aug 2020 16:10:33 +0000</pubDate>
      <link>https://dev.to/joni2nja/evaluating-readline-using-system-io-pipelines-performance-in-c-2io8</link>
      <guid>https://dev.to/joni2nja/evaluating-readline-using-system-io-pipelines-performance-in-c-2io8</guid>
      <description>&lt;h4&gt;
  
  
  Read string line by line using System.IO.Pipelines API in C
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8W7HriB3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A9i0fZ9otnPpsWN_C8YoH2w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8W7HriB3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A9i0fZ9otnPpsWN_C8YoH2w.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A typical approach for reading a string line by line from a file would probably be using &lt;a href="https://stackoverflow.com/questions/8037070/whats-the-fastest-way-to-read-a-text-file-line-by-line"&gt;ReadLine&lt;/a&gt; APIs. I have heard all good things about &lt;a href="https://devblogs.microsoft.com/dotnet/system-io-pipelines-high-performance-io-in-net/"&gt;System.IO.Pipelines&lt;/a&gt;, which was born from the work of the .NET Core team to make Kestrel one of the &lt;a href="https://www.techempower.com/benchmarks/#section=data-r19&amp;amp;hw=ph&amp;amp;test=plaintext"&gt;fastest web servers&lt;/a&gt;.&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f8He6Ns8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/EZI7ULoXQAEFCjK.jpg" alt="unknown tweet media content"&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--6OYWtO2n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1282411238602006529/l4lHaQHE_normal.jpg" alt="Ben Adams #BlackLivesMatter profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Ben Adams #BlackLivesMatter
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @ben_a_adams
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Round 19 of &lt;a href="https://twitter.com/TFBenchmarks"&gt;@TFBenchmarks&lt;/a&gt; is out and ASP​.NET Core on Linux racing to the top! &lt;br&gt;&lt;br&gt;Who would have thought .NET would have been fully OSS and top performer *on Linux* a several years ago? &lt;a href="https://twitter.com/hashtag/aspnetcore"&gt;#aspnetcore&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/dotnet"&gt;#dotnet&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a href="https://t.co/co3FzM5C1Z"&gt;techempower.com/benchmarks/#se…&lt;/a&gt; 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      23:04 PM - 28 May 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1266143330477453314" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1266143330477453314" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      168
      &lt;a href="https://twitter.com/intent/like?tweet_id=1266143330477453314" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      379
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;Although it is probably better suited for network socket IO, I was wondering how easy and how does it perform compared to the traditional ReadLine APIs? So I decided to give it a spin by creating simple benchmarks using &lt;a href="https://benchmarkdotnet.org/"&gt;BenchmarkDotNet&lt;/a&gt; as part of my learning journey.&lt;/p&gt;

&lt;p&gt;But, for this post, instead of using a file as the source of the stream, I decided to use in-memory, presumably more-stable-for-benchmark MemoryStream. Feel free to modify it to use a file as the stream source and try it yourself.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The code for ReadLine is so dead simple; nothing fancy here.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;em&gt;(My apologies for the possibly misleading method name&lt;/em&gt; &lt;em&gt;ReadLineUsingStringReaderAsync; it doesn’t use&lt;/em&gt; &lt;em&gt;StringReader class at all)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You will probably spot that unfamiliar C# 9.0 &lt;a href="https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/patterns3.md#pattern-combinators"&gt;Pattern Combinators&lt;/a&gt; is not null; Yes, I’m using the latest (at the time of writing) .NET 5 Preview 7 (5.0.0-preview.7) and the preview version of Visual Studio (Version 16.8.0 Preview 1.0). Don’t blame me, I love bleeding edge stuff!😎&lt;/p&gt;

&lt;p&gt;&lt;em&gt;See how&lt;/em&gt; &lt;em&gt;is not null is transformed&lt;/em&gt; &lt;a href="https://sharplab.io/#v2:EYLgtghgzgLgpgJwD4AEBMBGAsAKBQZgAJ1CBhQgb10JuKJQBZCBZACgEpLraeUMAGQlEIBeQgCJxAbm48aASwBmhVsPnCAdgHsYhDQFcANoc5Ucci4XkbdAD1GEMM85Z62A1O+euAvrMJ+OD5AA"&gt;&lt;em&gt;here&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To simplify the processing of a ReadOnlySequence, here I used SequenceReader; taken from the official sample &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/io/buffers#sequencereadert"&gt;here&lt;/a&gt;, modified it slightly to make it follow a similar pattern while (... is not null) as &lt;em&gt;ReadLineUsingStringReaderAsync&lt;/em&gt; does.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And finally, here is the result: 40 benchmarks in 15 minutes on my machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GjSTTlmv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A1FetdhtL7yBqLEQP2sRFyw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GjSTTlmv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A1FetdhtL7yBqLEQP2sRFyw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the gist version:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


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

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LineNumber : Value of the 'LineNumber' parameter
LineCharMultiplier : Value of the 'LineCharMultiplier' parameter
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
Ratio : Mean of the ratio distribution ([Current]/[Baseline])
RatioSD : Standard deviation of the ratio distribution ([Current]/[Baseline])
Gen 0 : GC Generation 0 collects per 1000 operations
Gen 1 : GC Generation 1 collects per 1000 operations
Gen 2 : GC Generation 2 collects per 1000 operations
Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)
Code Size : Native code size of the disassembled method(s)
1 ms : 1 Millisecond (0.001 sec)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can find the source code in my &lt;a href="https://github.com/jo-ninja/ReadLinesBenchmarks"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Pipelines versions are better in terms of memory usage (using less memory).&lt;/li&gt;
&lt;li&gt;In terms of speed, it is surprisingly slower than the &lt;em&gt;ordinary&lt;/em&gt; ReadLine version given the string length ≤ 80 (perhaps I am doing it wrong? Let me know! I am still learning!). It is starting to shine, getting faster and faster if the string length ≥ 90. (270% 🚀 faster for string length = 1000).&lt;/li&gt;
&lt;li&gt;Less GC pressure (a good thing) for Pipelines versions (Gen 0, Gen 1).&lt;/li&gt;
&lt;li&gt;The amount of code to write for the Pipelines version is longer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[Update] See &lt;a href="https://dev.to/joni2nja/evaluating-readline-using-system-io-pipelines-performance-in-c-part-2-pmf"&gt;part 2&lt;/a&gt; of this series for a better version! (Spoiler: faster on every test!)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;DISCLAIMER: Your mileage may vary. As with all performance work, each of the scenarios chosen for your application should be measured, measured and measured. There is no silver bullet.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Resources:&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devblogs.microsoft.com/dotnet/system-io-pipelines-high-performance-io-in-net/"&gt;System.IO.Pipelines: High performance IO in .NET&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/io/pipelines"&gt;System.IO.Pipelines in .NET&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/io/buffers#sequencereadert"&gt;Work with Buffers in .NET&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.stevejgordon.co.uk/an-introduction-to-sequencereader"&gt;An Introduction to SequenceReader by Steve Gordon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>benchmark</category>
      <category>csharp</category>
      <category>dotnetcore</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>【Sysinternals の Process Monitor でトラブルシューティング】謎のネットワークファイル取得失敗</title>
      <dc:creator>Joni 【ジョニー】</dc:creator>
      <pubDate>Fri, 14 Aug 2020 08:01:08 +0000</pubDate>
      <link>https://dev.to/joni2nja/sysinternals-process-monitor-2lm7</link>
      <guid>https://dev.to/joni2nja/sysinternals-process-monitor-2lm7</guid>
      <description>&lt;h4&gt;
  
  
  Sysinternals の Process Monitor を使い、謎のローカルネットワークファイルアクセス失敗のトラブルシューティングをします。
&lt;/h4&gt;

&lt;p&gt;あるWeb アプリケーションの要件としてローカルネットワークに存在するファイルを取得して Web 画面に表示させます。この Web アプリケーションは .NET Core Module で IIS 上で動作します。&lt;/p&gt;

&lt;p&gt;Visual Studio で ASP.NET Core アプリケーションの開発時は実は IIS は任意で、Launch Profile を変更することで IIS を使わず通常の .exe のように直接起動できます。&lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-azuretools.Dot-Net-Core-Debugging-With-Wsl2"&gt;.NET Core Debugging with WSL 2&lt;/a&gt; で WSL 2 でもデバッグできるようになります！&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YBM5hq5f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/921/1%2AlEynCLKIVhnremWzyJXxiQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YBM5hq5f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/921/1%2AlEynCLKIVhnremWzyJXxiQ.png" alt="Visual Studio Debug Profile"&gt;&lt;/a&gt;Visual Studio Debug Profile&lt;/p&gt;

&lt;p&gt;Windows Explorer やコマンドでそれを単独で起動できたり、別のPCにコピーして通常 .exe みたいに簡易に起動できたりしますのですごく便利です。&lt;/p&gt;

&lt;p&gt;ローカルネットワークにあるファイルを取得して表示するには色々方法がありますが、その一つは &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.io.directory.enumeratefilesystementries?view=netcore-3.1"&gt;Directory.EnumerateFileSystemEntries&lt;/a&gt; です。ローカルで単独 .exe を実行して問題なく ¥¥hogeIP¥directory01 のようにアクセスできた後、ローカルの IIS にデプロイして、問題なく動作したことを確認。&lt;/p&gt;

&lt;p&gt;よし、用意されていたテスト環境の AWS EC2 の IIS にデプロイしようぜ！&lt;/p&gt;

&lt;p&gt;デプロイ完了し、テストしてみたら、あれ、なぜディレクトリ内のファイルの表示ができてないんだ？&lt;/p&gt;

&lt;p&gt;空っぽだぞ！👀&lt;/p&gt;

&lt;p&gt;Windows Explorer で ¥¥hogeIP¥directory01 は普通にアクセスできたので、権限まわりが怪しい？😤&lt;/p&gt;

&lt;p&gt;エラーログを見てみたら、確かに &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.io.directory.enumeratefilesystementries?view=netcore-3.1"&gt;Directory.EnumerateFileSystemEntries&lt;/a&gt; の結果にファイルエントリがなくて、特に Exception もありません。プログラム側で try catch で潰している訳でもありません。権限問題であれば、API の &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.io.directory.enumeratefilesystementries?view=netcore-3.1"&gt;Docs&lt;/a&gt; によると SecurityException や UnauthorizedAccessException が出ているはず。それがないのが、謎です。&lt;/p&gt;

&lt;p&gt;単独 .exe で実行してみよう。 hoge.exe --urls http://*:5001 のようにポートを指定して起動します。あれ、単独で実行した場合は普通にアクセスできたぞ！ファイル一覧をちゃんと表示されました。&lt;/p&gt;

&lt;p&gt;もしかしたら IIS 関連の権限がダメなのかな？&lt;/p&gt;

&lt;p&gt;ダメもとで Windows の資格情報マネージャーで IP 認証情報を登録しておくと、どうでしょう？&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P932vFws--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ATPLuqSKqrQx1lnNo8ewZpQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P932vFws--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ATPLuqSKqrQx1lnNo8ewZpQ.png" alt="Windows の資格情報マネージャーで IP 認証情報を登録しておく"&gt;&lt;/a&gt;Windows の資格情報マネージャーで IP 認証情報を登録しておく&lt;/p&gt;

&lt;p&gt;うーん、状況変わらず。&lt;/p&gt;

&lt;p&gt;試しに IIS の &lt;a href="https://docs.microsoft.com/en-us/iis/manage/configuring-security/application-pool-identities#configuring-iis-application-pool-identities"&gt;アプリケーションプールアイデンティティアカウントを変更&lt;/a&gt;して管理者に設定してみよう。セキュリティ上ではオススメしないけど、とりあえず原因究明が先だ！&lt;/p&gt;

&lt;p&gt;管理者に変更してみても同じくアクセスできませんでした・・・IIS に最強の Administrator 権限割り当てやがったぞ！ｗ&lt;/p&gt;

&lt;p&gt;タスクマネージャーでちゃんと Administrator になっていることも確認できましたし。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ebNBS8li--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AHdofCMoLk9zqm1pZQ8mLjw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ebNBS8li--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AHdofCMoLk9zqm1pZQ8mLjw.png" alt="タスクマネージャー"&gt;&lt;/a&gt;タスクマネージャー&lt;/p&gt;

&lt;p&gt;Sysinternals の &lt;a href="https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer"&gt;Process Explorer&lt;/a&gt; でも確認しよう！&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--acifSMFj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AbFNpPAuYFx-lj5oyDRjuig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--acifSMFj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AbFNpPAuYFx-lj5oyDRjuig.png" alt="Process Explorer"&gt;&lt;/a&gt;Process Explorer&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer"&gt;Process Explorer&lt;/a&gt; で IIS ワーカープロセス (w3wp.exe) の子プロセスで Administrator として実行されていることも確認できましたので、まだアクセスできないのはなぜだ？&lt;/p&gt;

&lt;p&gt;こうなりましたら、Sysinternals の &lt;a href="https://docs.microsoft.com/en-us/sysinternals/downloads/procmon"&gt;Process Monitor&lt;/a&gt; でも使ってみますか！&lt;/p&gt;

&lt;p&gt;まず、単独 .exe で実行した時のログを取ります。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Om0PWWdV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Al9u5htEbQSFVKqnHFkdp2Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Om0PWWdV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Al9u5htEbQSFVKqnHFkdp2Q.png" alt="ネットワークのファイルアクセスOK"&gt;&lt;/a&gt;ネットワークのファイルアクセスOK&lt;/p&gt;

&lt;p&gt;はい、Result が SUCCESS で Detail にファイル名もちゃんと出ていますね。&lt;/p&gt;

&lt;p&gt;では、IIS で実行した時のログに比較してみましょう。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5G-dAA1a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Ak4BHO5OEMjPnjXFant0vgQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5G-dAA1a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Ak4BHO5OEMjPnjXFant0vgQ.png" alt="ネットワークのファイルアクセスエラー"&gt;&lt;/a&gt;ネットワークのファイルアクセスエラー&lt;/p&gt;

&lt;p&gt;おや、 LOGON FAILURE だと？&lt;/p&gt;

&lt;p&gt;その違いは何だ？&lt;/p&gt;

&lt;p&gt;待てよ。もしかして、Windows の Session ID が違うから？単独 .exe の場合の Windows Session ID は？&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PuLkp7r7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/507/1%2AnPzZMv9_r8_tdVHkpBG2Sw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PuLkp7r7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/507/1%2AnPzZMv9_r8_tdVHkpBG2Sw.png" alt="単独 .exe の場合の Windows Session ID"&gt;&lt;/a&gt;単独 .exe の場合の Windows Session ID&lt;/p&gt;

&lt;p&gt;IIS の場合は？&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I0AuPgnL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/529/1%2Al8WZC1QmWWB-RkugiddyhA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I0AuPgnL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/529/1%2Al8WZC1QmWWB-RkugiddyhA.png" alt="IISアカウントの場合の Windows Session ID"&gt;&lt;/a&gt;IISアカウントの場合の Windows Session ID&lt;/p&gt;

&lt;p&gt;ビンゴ！&lt;/p&gt;

&lt;p&gt;そっか、そりゃそうだ。システムとして実行するので Windows Session ID=0 は当たり前。&lt;/p&gt;

&lt;p&gt;Windows Session ID の違いで単独 .exe との動作が同じと保証できないもんね。LOGON FAILURE というログも取れましたので、調査報告としての原因はこれで材料が揃いました。&lt;/p&gt;

&lt;p&gt;Web アプリケーション側の対応として、ネットワークパスのそれぞれの認証情報をアプリケーション設定で変更可能にしておいて、アクセスする前にアプリケーション側が判断して該当サーバへ認証させます。そうすると、ディレクトリ内のファイルをちゃんと取得できるようになりました。&lt;/p&gt;

&lt;p&gt;とりあえず問題解決！&lt;/p&gt;

&lt;p&gt;普段なかなか使う場面がないですが、何年ぶりに &lt;a href="https://docs.microsoft.com/en-us/sysinternals/downloads/procmon"&gt;Process Monitor&lt;/a&gt; を使ったかな？&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.io.directory.enumeratefilesystementries?view=netcore-3.1"&gt;Directory.EnumerateFileSystemEntries&lt;/a&gt; はなぜ SecurityException や UnauthorizedAccessException をトリガーしていないのか、謎のままですが🙄。ローカルの Windows 10 で再現してみるとちゃんと例外が出ていますので、 Windows Server だと基本管理者として実行しているから管理者にはそんな例外なんて矛盾しているからトリガーしないとか？🤷‍♂️&lt;/p&gt;

&lt;h3&gt;
  
  
  まとめ
&lt;/h3&gt;

&lt;p&gt;アプリケーション側にエラーが出力されなくて、正常動作と見なした謎の挙動には、&lt;a href="https://docs.microsoft.com/en-us/sysinternals/downloads/procmon"&gt;Process Monitor&lt;/a&gt; を使ってトラブルシューティングし、ローカルネットワークのファイル取得失敗時のより OS レベルのログを取得することで原因特定と問題解決に繋がりました。🎉🎉🎉🎊🎊🎊&lt;/p&gt;

</description>
      <category>processmonitor</category>
      <category>sysinternals</category>
      <category>dotnet</category>
      <category>iis</category>
    </item>
    <item>
      <title>Consider using C# 8 with the .NET Framework</title>
      <dc:creator>Joni 【ジョニー】</dc:creator>
      <pubDate>Thu, 31 Oct 2019 22:01:03 +0000</pubDate>
      <link>https://dev.to/joni2nja/consider-using-c-8-with-the-net-framework-af6</link>
      <guid>https://dev.to/joni2nja/consider-using-c-8-with-the-net-framework-af6</guid>
      <description>&lt;p&gt;This post originally appeared on &lt;a href="https://medium.com/@joni2nja/consider-using-c-8-with-the-net-framework-9dceb20647c5"&gt;Medium&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Consider using C# 8 with the .NET Framework
&lt;/h3&gt;

&lt;p&gt;Yes, you read it right.&lt;/p&gt;

&lt;p&gt;According to:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/dotnet/building-c-8-0/"&gt;Building C# 8.0 | .NET Blog&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;… using C# 8.0 is only supported on platforms that implement .NET Standard 2.1.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When we read it, our mental model would naturally say, okay, no support for the .NET Framework. Goodbye. Yes, we know that .NET Core is the future. But what if your superpower stubborn classic thinking customer dictated to use the now-dead-and-stuck (read: mature) .NET Framework technology?&lt;/p&gt;

&lt;p&gt;A little good news for you. You can use some of the C# 8.0 features! 🎊&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Yes, C# 8 can be used with the .NET Framework&lt;/strong&gt; and other targets older than .NET Core 3.0/.NET Standard 2.1 in Visual Studio 2019 (or older versions of Visual Studio if you &lt;a href="https://stackoverflow.com/a/58190585/397817"&gt;install a Nuget package&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The C# 8/.NET Framework combination is &lt;strong&gt;not&lt;/strong&gt; officially supported by Microsoft. It is, they say, &lt;strong&gt;for experts only&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The C# 8/.NET Framework combination is not officially supported by Microsoft. It is, they say, for experts only.&lt;/p&gt;

&lt;p&gt;More on this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/56651472/does-c-sharp-8-support-the-net-framework"&gt;Does C# 8 support the .NET Framework?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After playing around with C# 8 for a while, I would definitely say, &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references"&gt;nullable reference types&lt;/a&gt; are awesome! The compiler analyzes the flow of your code to see if a null value could make it to where you use it. It did catch my silly copy-pasted-and-then-forgot-to-edit bugs! Thanks!&lt;/p&gt;

&lt;p&gt;Make sure to check the &lt;strong&gt;C# 8.0 Feature Compatibility&lt;/strong&gt; table from Stuart Lang’s post as well:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/stuartblang/c-8-0-and-net-standard-2-0-doing-unsupported-things-3dk8-temp-slug-2870289"&gt;C# 8.0 and .NET Standard 2.0 - Doing Unsupported Things&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Look at that. &lt;strong&gt;&lt;em&gt;Support Category = 1 is Syntax Only — Language features that are purely syntax will just work!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s prove it by adding &lt;a href="https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build"&gt;Directory.Build.props&lt;/a&gt; file in the root directory so that every .csproj (project file) in the solution will inherit the settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;

&amp;lt;Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&amp;gt;

  &amp;lt;PropertyGroup&amp;gt;

    &amp;lt;LangVersion&amp;gt;latest&amp;lt;/LangVersion&amp;gt;

    &amp;lt;Nullable&amp;gt;enable&amp;lt;/Nullable&amp;gt;

  &amp;lt;/PropertyGroup&amp;gt;

&amp;lt;/Project&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;and then write this crazy method.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Owtjq36q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AZxknVyCnzBRN3CQiMT49Pw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Owtjq36q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AZxknVyCnzBRN3CQiMT49Pw.png" alt=""&gt;&lt;/a&gt;C# 8.0&lt;/p&gt;

&lt;p&gt;Compile and then decompile it using &lt;a href="https://github.com/0xd4d/dnSpy"&gt;dnSpy&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oonY3BJz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A0-Jlf9kxgiWXstsLKYmj9w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oonY3BJz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A0-Jlf9kxgiWXstsLKYmj9w.png" alt=""&gt;&lt;/a&gt;Decompiled code&lt;/p&gt;

&lt;p&gt;Whoah! We have saved a bunch of keystrokes!&lt;/p&gt;

&lt;p&gt;My favorite feature is &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#switch-expressions"&gt;&lt;strong&gt;“switch expressions.”&lt;/strong&gt;&lt;/a&gt; Super impressed with it.&lt;/p&gt;

&lt;p&gt;What is your favorite one?&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>【ふくてん】 Fukuoka.NET Conf 2019の開催＆登壇</title>
      <dc:creator>Joni 【ジョニー】</dc:creator>
      <pubDate>Mon, 14 Oct 2019 12:16:20 +0000</pubDate>
      <link>https://dev.to/joni2nja/fukuoka-net-conf-2019-38ek</link>
      <guid>https://dev.to/joni2nja/fukuoka-net-conf-2019-38ek</guid>
      <description>&lt;h1&gt;
  
  
  Fukuoka.NET Conf 2019
&lt;/h1&gt;

&lt;p&gt;2019/10/12 にふくてん .NET Conf 2019 の福岡版ローカルイベント無事開催！&lt;br&gt;
🌀強風の中、たくさんの方にご参加いただき、誠にありがとうございました。&lt;br&gt;
イベントページ：&lt;br&gt;
&lt;a href="https://fukuten.connpass.com/event/143452/"&gt;https://fukuten.connpass.com/event/143452/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;最初のセッションはなんと&lt;a href="https://www.dotnetconf.net/speakers#scott-hanselman"&gt;Scott Hanselman&lt;/a&gt; の動画！リアルタイムではなく、日本での .NET Conf 向けに動画を用意してくれました！&lt;br&gt;
長年の大ファンとして凄く嬉しかったです。いつか福岡へ来てくれないかな？？ｗ&lt;/p&gt;
&lt;h1&gt;
  
  
  ブログまとめ
&lt;/h1&gt;

&lt;p&gt;Microsoft MVP 松村さん通称「MLBお兄さん」と石橋さんのブログまとめはこちら↓↓↓ 是非チェックしてみてください♪&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;MLBお兄さん投稿：&lt;br&gt;
&lt;a href="https://tsubalog.hatenablog.com/entry/2019/10/13/154511"&gt;Fukuoka.NET Conf 2019を開催しました＆登壇をしました&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;石橋さん投稿：&lt;br&gt;
&lt;a href="https://rupic.hatenablog.com/entry/2019/10/13/155233"&gt;Fukuoka.NET Conf 2019 開催しました&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Twitter まとめはこちら↓&lt;br&gt;
&lt;a href="https://togetter.com/li/1416223"&gt;Fukuoka.NET Conf 2019 まとめ&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  「.NET Core 3.0 で Blazor を使用した​フルスタック C# Web アプリ​の構築」登壇資料
&lt;/h1&gt;

&lt;p&gt;自分の登壇資料はこちら↓&lt;br&gt;
&lt;iframe src="//www.slideshare.net/slideshow/embed_code/key/iJVOLMR5g4tMgZ" alt="iJVOLMR5g4tMgZ on slideshare.net" width="100%" height="450"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SSkYwC5k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ehwf91eli95ryyw98mdg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SSkYwC5k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ehwf91eli95ryyw98mdg.jpg" alt="Me"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;実はスライド作成は前日までブラッシュアップしていたのですが、どんな Blazor スクリーンショットをスライドに載せるか検討していて、ついちょい深いデバッグしていたら、フレームワーク内のスペルミスを発見！そして GitHub 上の Pull Request （プルリク）を送信しました。&lt;/p&gt;


&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/dotnet/aspnetcore/pull/14925"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg"&gt;
      &lt;span class="issue-title"&gt;
        Fixes typo in StaticComponentRenderer.cs
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#14925&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/jo-ninja"&gt;
        &lt;img class="github-liquid-tag-img" src="https://res.cloudinary.com/practicaldev/image/fetch/s--hbQAZNbS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars1.githubusercontent.com/u/29521868%3Fv%3D4" alt="jo-ninja avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/jo-ninja"&gt;jo-ninja&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/dotnet/aspnetcore/pull/14925"&gt;&lt;time&gt;Oct 11, 2019&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      &lt;p&gt;Fixes "reponse" =&amp;gt; "response"&lt;/p&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/dotnet/aspnetcore/pull/14925"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;その数日前も、気づいた点を発見し、プルリクを送信しました。&lt;/p&gt;


&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/dotnet/docs/pull/14984"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg"&gt;
      &lt;span class="issue-title"&gt;
        Add missing @ symbols in pages-routing-layouts.md
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#14984&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/jo-ninja"&gt;
        &lt;img class="github-liquid-tag-img" src="https://res.cloudinary.com/practicaldev/image/fetch/s--hbQAZNbS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars1.githubusercontent.com/u/29521868%3Fv%3D4" alt="jo-ninja avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/jo-ninja"&gt;jo-ninja&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/dotnet/docs/pull/14984"&gt;&lt;time&gt;Oct 06, 2019&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      &lt;p&gt;Add missing @ symbols in the sample code.&lt;/p&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/dotnet/docs/pull/14984"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/dotnet/docs/pull/14982"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg"&gt;
      &lt;span class="issue-title"&gt;
        Fixes invalid parameter name in components.md
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#14982&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/jo-ninja"&gt;
        &lt;img class="github-liquid-tag-img" src="https://res.cloudinary.com/practicaldev/image/fetch/s--hbQAZNbS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars1.githubusercontent.com/u/29521868%3Fv%3D4" alt="jo-ninja avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/jo-ninja"&gt;jo-ninja&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/dotnet/docs/pull/14982"&gt;&lt;time&gt;Oct 06, 2019&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      &lt;p&gt;Fixes invalid parameter name in SimpleListView.razor sample code&lt;/p&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/dotnet/docs/pull/14982"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Blazor は比較的に新しい技術でもあり、&lt;a href="https://docs.microsoft.com/en-us/aspnet/core/blazor/?view=aspnetcore-3.0"&gt;公式ドキュメント&lt;/a&gt;はこれからもブラッシュアップされていくと思いますので、皆さんのフィードバックも不可欠ではないでしょうか。&lt;/p&gt;




&lt;p&gt;次回のふくてん、皆様のご参加をお待ちしています♪♪ ✨🎉🎊&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>blazor</category>
      <category>dotnetconf</category>
    </item>
    <item>
      <title>VS Code リモート開発で .NET Framework の .exe をビルドしてみた</title>
      <dc:creator>Joni 【ジョニー】</dc:creator>
      <pubDate>Thu, 19 Sep 2019 12:31:49 +0000</pubDate>
      <link>https://dev.to/joni2nja/vs-code-net-framework-exe-4c1p</link>
      <guid>https://dev.to/joni2nja/vs-code-net-framework-exe-4c1p</guid>
      <description>&lt;p&gt;This post originally appeared on &lt;a href="https://medium.com/@joni2nja/vs-code-remote-development-build-net-framework-89eaa99d96d1"&gt;Medium&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  VS Code リモート開発で .NET Framework の .exe をビルドしてみた
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Linux/Mac環境で .NET Framework プロジェクトをビルド可能に～
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8X8rB33G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/960/1%2As5i5PA6XT8TCN593JOy5AQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8X8rB33G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/960/1%2As5i5PA6XT8TCN593JOy5AQ.png" alt=""&gt;&lt;/a&gt;Visual Studio Code&lt;/p&gt;

&lt;p&gt;以前 Twitter で見たのですが、Linux/Mac 環境でフル .NET Framework をターゲットし、ビルドができるらしい。&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--DI112gqI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/621406729184657409/0N2MoalM_normal.png" alt="Muhammad Rehan Saeed profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Muhammad Rehan Saeed
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @rehansaeeduk
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      You can now target and build full .NET Framework on Linux &amp;amp; Mac via Mono with official support. Add this package:&lt;br&gt;&lt;br&gt;&amp;lt;PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" Version="1.0.0-preview.2" /&amp;gt;&lt;br&gt;&lt;br&gt;&lt;a href="https://twitter.com/hashtag/dotnet"&gt;#dotnet&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/dotnet"&gt;#dotnet&lt;/a&gt;core&lt;br&gt;&lt;br&gt;&lt;a href="https://t.co/dKBKpsTUyU"&gt;github.com/Microsoft/dotn…&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      13:11 PM - 02 Jun 2019
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1135172099499331584" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1135172099499331584" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      66
      &lt;a href="https://twitter.com/intent/like?tweet_id=1135172099499331584" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      122
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;&lt;a href="https://github.com/Microsoft/dotnet/tree/master/releases/reference-assemblies"&gt;.NET Framework Targeting Pack Nuget Packages (Preview)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;できるとのことなので、Linux マシンで普通にビルドしても面白くないので、今回は &lt;a href="https://code.visualstudio.com/docs/remote/remote-overview"&gt;Visual Studio Code Remote Development（リモート開発）&lt;/a&gt;を使って、ビルドして検証してみたいと思います。&lt;/p&gt;

&lt;p&gt;まずは VS Code を起動し、 &lt;code&gt;F1&lt;/code&gt; 押下、コマンドを打ちます。 &lt;code&gt;rem ad&lt;/code&gt; という風に必要最低限の文字列を打つだけで検索結果がヒットしますので、凄く便利です。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8MNJxzUz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/666/1%2AlBGmKFSgzCachLMogfDfAg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8MNJxzUz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/666/1%2AlBGmKFSgzCachLMogfDfAg.png" alt=""&gt;&lt;/a&gt;必要最低限の文字列を打つことで検索&lt;/p&gt;

&lt;p&gt;&lt;code&gt;C# (.NET Core Latest)&lt;/code&gt; を選択します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wy89ioLO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/624/1%2AEWbxnWoo_IQbu7So5i7b6Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wy89ioLO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/624/1%2AEWbxnWoo_IQbu7So5i7b6Q.png" alt=""&gt;&lt;/a&gt;C# (.NET Core Latest) を選択&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Reopen in Container&lt;/code&gt; を選択します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kzfxNDZK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/470/1%2AJCi4NBxgO4B3h-6hesbPhg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kzfxNDZK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/470/1%2AJCi4NBxgO4B3h-6hesbPhg.png" alt=""&gt;&lt;/a&gt;Reopen in Container を選択&lt;/p&gt;

&lt;p&gt;そして、開きました。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_h1QcQbT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/3096/1%2AT0wV1BrjBg4OiG16_-6EQw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_h1QcQbT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/3096/1%2AT0wV1BrjBg4OiG16_-6EQw.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://miro.medium.com/max/3096/1*T0wV1BrjBg4OiG16_-6EQw.png"&gt;(高解像度画像を表示)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;左側は &lt;a href="https://devblogs.microsoft.com/commandline/introducing-windows-terminal/"&gt;Windows Terminal&lt;/a&gt; で &lt;code&gt;docker events&lt;/code&gt; コマンドの結果をリアルタイムで表示しています。右側は VS Code リモート開発の準備ができた画面です。&lt;/p&gt;

&lt;p&gt;VS Code の Terminal で &lt;code&gt;dotnet new console&lt;/code&gt; を打って新規コンソールアプリケーションを作成します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LchYOBFw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AEz-jEUAp5G0kx0Ms94i2FQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LchYOBFw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AEz-jEUAp5G0kx0Ms94i2FQ.png" alt=""&gt;&lt;/a&gt;dotnet new console&lt;br&gt;
&lt;a href="https://miro.medium.com/max/1263/1*Ez-jEUAp5G0kx0Ms94i2FQ.png"&gt;(高解像度画像を表示)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;プロジェクトファイルを生成され、デフォルトで .csproj ファイルはこんな感じで作られます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RMN0mU4s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/545/1%2AD1-QC-box0tbK5HH9kF3vw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RMN0mU4s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/545/1%2AD1-QC-box0tbK5HH9kF3vw.png" alt=""&gt;&lt;/a&gt;作成された .csproj ファイル&lt;/p&gt;

&lt;p&gt;&lt;code&gt;netcoreapp2.2&lt;/code&gt; を削除して、 &lt;code&gt;net48&lt;/code&gt; に変更します。 &lt;code&gt;net48&lt;/code&gt; は &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/frameworks#supported-target-framework-versions"&gt;.NET Framework 4.8 の TFM (Target Framework Monikers)&lt;/a&gt; です。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet build&lt;/code&gt; コマンドでビルドをしてみると、エラーです。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A--9q6r---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1000/1%2AEE26QU-2KG-_dh8HjPdlDw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A--9q6r---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1000/1%2AEE26QU-2KG-_dh8HjPdlDw.png" alt=""&gt;&lt;/a&gt;dotnet build でビルド&lt;br&gt;
&lt;a href="https://miro.medium.com/max/1215/1*EE26QU-2KG-_dh8HjPdlDw.png"&gt;(高解像度画像を表示)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;まあ、エラーは当たり前ですね。Linux 環境で普通に .NET Framework プロジェクトをビルドできない訳ですから。ビルドできるようにするには &lt;strong&gt;Microsoft .NET Framework Reference Assemblies&lt;/strong&gt; が必要です。&lt;code&gt;PackageReference&lt;/code&gt; で定義し、再度ビルドしてみます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8meHFOIA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AysVshjgnJodoh87esvK_6w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8meHFOIA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AysVshjgnJodoh87esvK_6w.png" alt=""&gt;&lt;/a&gt;PackageReference 追加&lt;br&gt;
&lt;a href="https://miro.medium.com/max/1960/1*ysVshjgnJodoh87esvK_6w.png"&gt;(高解像度画像を表示)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;お～！(≧▽≦)&lt;/p&gt;

&lt;p&gt;宣伝通り、ビルドできましたね！&lt;br&gt;&lt;br&gt;
.exe ファイルちゃんと生成されています！&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.nuget.org/packages/Microsoft.NETFramework.ReferenceAssemblies/1.0.0-preview.2"&gt;NuGet&lt;/a&gt; サイトで &lt;code&gt;Microsoft.NETFramework.ReferenceAssemblies&lt;/code&gt; を覗いてみましょう。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--18E6cn9G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/956/1%2AYZaGST72XhQHz3xRtxEm8Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--18E6cn9G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/956/1%2AYZaGST72XhQHz3xRtxEm8Q.png" alt=""&gt;&lt;/a&gt;NuGet: Microsoft.NETFramework.ReferenceAssemblies&lt;/p&gt;

&lt;p&gt;.NET Framework 4.8 はもちろんのこと、さかのぼって古い .NET Framework 2.0 も対応？！ これは凄くないですか！レガシーシステム向けでちゃんと Microsoft がサポートしているということですね。&lt;/p&gt;

&lt;p&gt;はい、次！試しに、 &lt;code&gt;dotnet run&lt;/code&gt; を実行してみます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bM_5Qey1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AFGUmtDEnsnAD3QFnUYQiRQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bM_5Qey1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AFGUmtDEnsnAD3QFnUYQiRQ.png" alt=""&gt;&lt;/a&gt;dotnet run エラー&lt;br&gt;
&lt;a href="https://miro.medium.com/max/1960/1*FGUmtDEnsnAD3QFnUYQiRQ.png"&gt;(高解像度画像を表示)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;エラーです。これも当然のことですね。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System.ComponentModel.Win32Exception (8): Exec format error
   at Interop.Sys.ForkAndExecProcess(String filename, String[] argv, String[] envp, String cwd, Boolean redirectStdin, Boolean redirectStdout, Boolean redirectStderr, Boolean setUser, UInt32 userId, UInt32 groupId, Int32&amp;amp; lpChildPid, Int32&amp;amp; stdinFd, Int32&amp;amp; stdoutFd, Int32&amp;amp; stderrFd, Boolean shouldThrow)
   at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start()
   at Microsoft.DotNet.Cli.Utils.Command.Execute()
   at Microsoft.DotNet.Tools.Run.RunCommand.Start()
   at Microsoft.DotNet.Tools.Run.RunCommand.Run(String[] args)
   at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, ITelemetry telemetryClient)
   at Microsoft.DotNet.Cli.Program.Main(String[] args)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Win32Exception&lt;/code&gt; 例外発生しましたね。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet run&lt;/code&gt; は .NET Core アプリを実行するコマンドですが、生成された .exe ファイルを bash で直接実行したらどうなるでしょう？&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iz6Vvx5Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AgphtjbIHgMQOVakYmMBH7g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iz6Vvx5Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AgphtjbIHgMQOVakYmMBH7g.png" alt=""&gt;&lt;/a&gt;bash でバイナリを実行する&lt;br&gt;
&lt;a href="https://miro.medium.com/max/1960/1*gphtjbIHgMQOVakYmMBH7g.png"&gt;(高解像度画像を表示)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;当然ながら、 .exe ファイルを Linux 上で直接実行できないよ～！&lt;/p&gt;

&lt;p&gt;では、 Windows Explorer を開きます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NnR_6qEa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/976/1%2Afa32DsSmOcqTRojN2u3SxQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NnR_6qEa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/976/1%2Afa32DsSmOcqTRojN2u3SxQ.png" alt=""&gt;&lt;/a&gt;Windows Explorer を開く&lt;/p&gt;

&lt;p&gt;そこからダブルクリックし、実行します！&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j0w5xhLJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1954/1%2AKWFhlFZgE5vEQa3tYxzG1g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j0w5xhLJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1954/1%2AKWFhlFZgE5vEQa3tYxzG1g.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://miro.medium.com/max/1954/1*KWFhlFZgE5vEQa3tYxzG1g.png"&gt;(高解像度画像を表示)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;おぉ～～！&lt;/p&gt;

&lt;p&gt;非常にシンプルなコンソールアプリの検証になりますが、 Linux 環境でビルドした .NET Framework .exe ファイルはちゃんと Windows で実行できたことをこれで証明されましたね！🎉🎉🎉&lt;/p&gt;

&lt;p&gt;ここまでは一応検証目標を達成しましたが、今度はマルチターゲットを検証してみたいと思います。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;TargetFramework&lt;/code&gt; を修正し、複数の .NET Framework を対象にしてビルドしたいと思います。下記のように修正してビルドします。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;TargetFrameworks&amp;gt;net48;netcoreapp2.2&amp;lt;/TargetFrameworks&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;⚠注：TargetFramework ではなく 複数形 TargetFramework &lt;strong&gt;s&lt;/strong&gt; （語尾に「s」）&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2CKNYNWg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2APD_DGG9iFHqQgIQJw7v1HQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2CKNYNWg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2APD_DGG9iFHqQgIQJw7v1HQ.png" alt=""&gt;&lt;/a&gt;マルチターゲット&lt;br&gt;
&lt;a href="https://miro.medium.com/max/1960/1*PD_DGG9iFHqQgIQJw7v1HQ.png"&gt;(高解像度画像を表示)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;これで .NET Framework 4.8 と .NET Core 2.2 それぞれのバイナリが出来上がりました！👏👏👏&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/0xd4d/dnSpy"&gt;dnSpy&lt;/a&gt; で覗いてみましょう。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aD0xh1zO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AYOzayLn4JPA1TZTekueqUg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aD0xh1zO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AYOzayLn4JPA1TZTekueqUg.png" alt=""&gt;&lt;/a&gt;dnSpy で確認&lt;br&gt;
&lt;a href="https://miro.medium.com/max/1636/1*YOzayLn4JPA1TZTekueqUg.png"&gt;(高解像度画像を表示)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Linux 環境で .NET Core 2.2 の .dll を実行してみましょう！&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CVuO1w3F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AarTM_Ist5Af9SLgSjMNl2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CVuO1w3F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AarTM_Ist5Af9SLgSjMNl2g.png" alt=""&gt;&lt;/a&gt;bash で実行&lt;br&gt;
&lt;a href="https://miro.medium.com/max/1960/1*arTM_Ist5Af9SLgSjMNl2g.png"&gt;(高解像度画像を表示)&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello World!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;実行できましたね。&lt;/p&gt;

&lt;p&gt;Windows Explorer を起動します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d444IpL7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/976/1%2Aph6McURoiKTwfDmmMyJi-Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d444IpL7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/976/1%2Aph6McURoiKTwfDmmMyJi-Q.png" alt=""&gt;&lt;/a&gt;Windows Explorer&lt;/p&gt;

&lt;p&gt;そこから、アドレスバーで &lt;code&gt;cmd&lt;/code&gt; を打って、&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0z6k8g8g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/976/1%2ASM9L1_668T6jFW3GdW63wQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0z6k8g8g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/976/1%2ASM9L1_668T6jFW3GdW63wQ.png" alt=""&gt;&lt;/a&gt;cmd&lt;/p&gt;

&lt;p&gt;ENTERキー押下！これで Explorer で開いているディレクトリがカレントディレクトリとして設定され cmd を起動されます。&lt;/p&gt;

&lt;p&gt;先ほどと同じコマンド &lt;code&gt;dotnet RefAsm.dll&lt;/code&gt; を実行します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TYL_aaME--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AoyERn0sZybZOPVXNmAQEIg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TYL_aaME--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AoyERn0sZybZOPVXNmAQEIg.png" alt=""&gt;&lt;/a&gt;Hello World!&lt;br&gt;
&lt;a href="https://miro.medium.com/max/1953/1*oyERn0sZybZOPVXNmAQEIg.png"&gt;(高解像度画像を表示)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Windows でも実行できてますね！&lt;/p&gt;

&lt;p&gt;そう、 .NET Core は&lt;a href="https://docs.microsoft.com/ja-jp/dotnet/core/"&gt;クロスプラットフォーム&lt;/a&gt;なのです ✨✨✨&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>dotnetcore</category>
      <category>vscode</category>
      <category>docker</category>
    </item>
    <item>
      <title>Configure HttpClientFactory to Use Fiddler in .NET Core Microservices-based Docker Containers</title>
      <dc:creator>Joni 【ジョニー】</dc:creator>
      <pubDate>Sat, 15 Jun 2019 15:26:42 +0000</pubDate>
      <link>https://dev.to/joni2nja/configure-httpclientfactory-to-use-fiddler-in-net-core-microservices-based-docker-containers-16kh</link>
      <guid>https://dev.to/joni2nja/configure-httpclientfactory-to-use-fiddler-in-net-core-microservices-based-docker-containers-16kh</guid>
      <description>&lt;p&gt;This post originally appeared on &lt;a href="https://medium.com/@joni2nja/configure-httpclientfactory-to-use-fiddler-in-net-core-microservices-based-docker-containers-2540bd87c14"&gt;Medium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ever wonder how to configure your Dockerized applications to use Fiddler?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9ugtPHD3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ARrzfRcoC2Uh6Igm4S4eKnw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9ugtPHD3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ARrzfRcoC2Uh6Igm4S4eKnw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If all of the following conditions are true, then this post might help you. Hopefully.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You are developing microservices-based applications using &lt;a href="https://dot.net"&gt;.NET Core&lt;/a&gt; 2.1 or above&lt;/li&gt;
&lt;li&gt;You develop using &lt;a href="https://docs.docker.com/docker-for-windows/"&gt;Docker Desktop for Windows&lt;/a&gt; (minimum version: 18.03)&lt;/li&gt;
&lt;li&gt;You are using &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests#what-is-httpclientfactory"&gt;HttpClientFactory&lt;/a&gt;, an opinionated factory for creating HttpClient instances&lt;/li&gt;
&lt;li&gt;You love &lt;a href="https://www.telerik.com/fiddler"&gt;Fiddler&lt;/a&gt; and trying to configure your HttpClient to use Fiddler as the debugging proxy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s say our Docker container application has the following &lt;code&gt;HttpClientFactory&lt;/code&gt; setup in &lt;code&gt;Startup.cs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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="nf"&gt;AddHttpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mySuperSplendidMarvelousAmazingService"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetHandlerLifetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromMinutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPolicyHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;GetRetryPolicy&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPolicyHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;GetCircuitBreakerPolicy&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that &lt;code&gt;AddPolicyHandler(...)&lt;/code&gt; might be a typical Microservices pattern you can possibly use. See “&lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/implement-resilient-applications/implement-http-call-retries-exponential-backoff-polly"&gt;.NET Microservices: Architecture for Containerized .NET Applications&lt;/a&gt;” references.&lt;/p&gt;

&lt;p&gt;Now, to configure the &lt;code&gt;HttpClient&lt;/code&gt; to “talk” to the Fiddler on the host port 8888 (&lt;a href="https://docs.telerik.com/fiddler/configure-fiddler/tasks/UseFiddlerAsReverseProxy"&gt;Fiddler listens on port 8888 by default&lt;/a&gt;), we will need to know the host IP address. Thanks to Docker v18.03, we can use the special DNS name &lt;code&gt;host.docker.internal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Refer to the documentation for more details:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/docker-for-windows/networking/"&gt;Networking features in Docker Desktop for Windows&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So let’s use that special DNS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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="nf"&gt;AddHttpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mySuperSplendidMarvelousAmazingService"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetHandlerLifetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromMinutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;// ADD THIS 👇👇👇&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigurePrimaryHttpMessageHandler&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;  
  &lt;span class="p"&gt;{&lt;/span&gt;  
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HttpClientHandler&lt;/span&gt;  
      &lt;span class="p"&gt;{&lt;/span&gt;  
          &lt;span class="n"&gt;Proxy&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;WebProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://host.docker.internal:8888"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;  
          &lt;span class="n"&gt;UseProxy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&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="nf"&gt;AddPolicyHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;GetRetryPolicy&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPolicyHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;GetCircuitBreakerPolicy&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That’s it! Now we should be able to inspect the requests/responses in Fiddler.&lt;/p&gt;

&lt;p&gt;But wait 🛑⛔🚫!! We don’t want to ship that debugging code to the production, right? Of course not. But sometimes we just want to be able to use it during debugging with a simple flip. Let’s explore some possible solutions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Preprocessor Directive&lt;/li&gt;
&lt;li&gt;Use ConditionalAttribute&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Preprocessor Directive
&lt;/h3&gt;

&lt;p&gt;We accomplish this by using a C# &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-if"&gt;&lt;em&gt;preprocessor directive&lt;/em&gt;&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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="nf"&gt;AddHttpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mySuperSplendidMarvelousAmazingService"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetHandlerLifetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromMinutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="cp"&gt;#if DEBUG 😎
&lt;/span&gt;  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigurePrimaryHttpMessageHandler&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HttpClientHandler&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;Proxy&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;WebProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://host.docker.internal:8888"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;UseProxy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="cp"&gt;#endif
&lt;/span&gt;  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPolicyHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;GetRetryPolicy&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPolicyHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;GetCircuitBreakerPolicy&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This way, on the production build, it won’t be compiled into Microsoft Intermediate Language (MSIL, or IL for short).&lt;/p&gt;

&lt;p&gt;Looks good. Until it’s not. It will fail if we forget to launch Fiddler every time we start our application in the debug mode. So, a better alternative, define and use our own custom symbol, for example: &lt;code&gt;ENABLE_FIDDLER_DEBUG_PROXY&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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="nf"&gt;AddHttpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mySuperSplendidMarvelousAmazingService"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetHandlerLifetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromMinutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="cp"&gt;#if ENABLE_FIDDLER_DEBUG_PROXY 😍
&lt;/span&gt;  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigurePrimaryHttpMessageHandler&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HttpClientHandler&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;Proxy&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;WebProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://host.docker.internal:8888"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;UseProxy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="cp"&gt;#endif
&lt;/span&gt;  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPolicyHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;GetRetryPolicy&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPolicyHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;GetCircuitBreakerPolicy&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And define it only when we really need it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rPj8Q0dj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/660/1%2AAgESqiTbEb_KXnLoWdvzZA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rPj8Q0dj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/660/1%2AAgESqiTbEb_KXnLoWdvzZA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome! 👍&lt;/p&gt;

&lt;h3&gt;
  
  
  Use ConditionalAttribute
&lt;/h3&gt;

&lt;p&gt;Another possible solution, make use of &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.conditionalattribute"&gt;ConditionalAttribute&lt;/a&gt;. Let’s add an extension method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;class&lt;/span&gt; &lt;span class="nc"&gt;FiddlerExtensions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Conditional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ENABLE_FIDDLER_DEBUG_PROXY"&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="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;AddFiddler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;IHttpClientBuilder&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigurePrimaryHttpMessageHandler&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HttpClientHandler&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Proxy&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;WebProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://host.docker.internal:8888"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;UseProxy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&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;and use it like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddHttpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mySuperSplendidMarvelousAmazingService"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetHandlerLifetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromMinutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPolicyHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;GetRetryPolicy&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPolicyHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;GetCircuitBreakerPolicy&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddFiddler&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The beauty of this is, the &lt;code&gt;builder.AddFidler()&lt;/code&gt; won’t be included in the IL if we don’t have &lt;code&gt;ENABLE_FIDDLER_DEBUG_PROXY&lt;/code&gt; defined.&lt;/p&gt;

&lt;p&gt;Now, the ugly part, we can’t continue chaining the method calls because it will end up being removed from the IL altogether, thus we are introducing a variable &lt;code&gt;builder&lt;/code&gt; here. You can use &lt;a href="https://github.com/icsharpcode/ILSpy"&gt;ILSpy&lt;/a&gt; or &lt;a href="https://github.com/0xd4d/dnSpy"&gt;dnSpy&lt;/a&gt; to disassemble and verify this behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus tips!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is another cool trick for debugging: &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.debugger.isattached"&gt;Debugger.IsAttached&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Gets a value that indicates whether a debugger is attached to the process.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Debugger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsAttached&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;This might be useful for some certain scenarios, but I don’t think I will use it for this scenario.&lt;/p&gt;

&lt;p&gt;What’s your solution?&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>fiddler</category>
      <category>docker</category>
      <category>dotnetcore</category>
    </item>
    <item>
      <title>Generating Swagger Example Dynamic Request Payload with Swashbuckle</title>
      <dc:creator>Joni 【ジョニー】</dc:creator>
      <pubDate>Tue, 21 May 2019 15:35:53 +0000</pubDate>
      <link>https://dev.to/joni2nja/generating-swagger-example-dynamic-request-payload-with-swashbuckle-4lej</link>
      <guid>https://dev.to/joni2nja/generating-swagger-example-dynamic-request-payload-with-swashbuckle-4lej</guid>
      <description>&lt;p&gt;This post originally appeared on &lt;a href="https://medium.com/@joni2nja/generating-swagger-example-dynamic-request-payload-with-swashbuckle-77c09127392c" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;New to Swashbuckle? See this official&lt;/em&gt; &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-2.2&amp;amp;tabs=visual-studio" rel="noopener noreferrer"&gt;&lt;em&gt;“Get started with Swashbuckle and ASP.NET Core.”&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can generate Swagger example requests with Swashbuckle, see &lt;a href="https://mattfrear.com/2016/01/25/generating-swagger-example-requests-with-swashbuckle/" rel="noopener noreferrer"&gt;this post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s say we have the following endpoint:&lt;/p&gt;

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

&lt;p&gt;Ignore the weird implementation, it just a sample. Focus on the method signature.&lt;/p&gt;

&lt;p&gt;And here is the Swagger UI page:&lt;/p&gt;

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

&lt;p&gt;&lt;em&gt;Note that this post is using&lt;/em&gt; &lt;a href="https://github.com/domaindrivendev/Swashbuckle.AspNetCore/tree/v3.0.0" rel="noopener noreferrer"&gt;&lt;em&gt;Swashbuckle.AspNetCore version 3.0&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now suppose we have no choice but to make it accepting dynamic payload — perhaps due to requirement changes from the client. So we change the &lt;code&gt;PostThorRequest request&lt;/code&gt; to &lt;code&gt;Jobject request&lt;/code&gt; like so:&lt;/p&gt;

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

&lt;p&gt;Now when we run it…&lt;/p&gt;

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

&lt;p&gt;Uh oh…See that, the Example Value is gone!&lt;/p&gt;

&lt;p&gt;How to fix this?&lt;/p&gt;

&lt;p&gt;Changing the first parameter of SwaggerRequestExample type to Jobject seems to fix it.&lt;/p&gt;

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

&lt;p&gt;and…&lt;/p&gt;

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

&lt;p&gt;Voila! It’s back!&lt;/p&gt;

&lt;p&gt;Note that this might be just one way of the possible solutions that work. While it does work, personally, I don’t recommend this kind of dynamic request approach for public facing APIs.&lt;/p&gt;

</description>
      <category>swashbuckle</category>
      <category>aspnetcore</category>
    </item>
    <item>
      <title>IdentityServer — ConfigurationDbContext でのクロスコンテキストトランザクション</title>
      <dc:creator>Joni 【ジョニー】</dc:creator>
      <pubDate>Tue, 30 Apr 2019 12:36:45 +0000</pubDate>
      <link>https://dev.to/joni2nja/identityserver-configurationdbcontext-1nb4</link>
      <guid>https://dev.to/joni2nja/identityserver-configurationdbcontext-1nb4</guid>
      <description>&lt;p&gt;This post originally appeared on &lt;a href="https://medium.com/@joni2nja/identityserver-configurationdbcontext-%E3%81%A7%E3%81%AE%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B3%E3%83%B3%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B6%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3-8b40f5019afc" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  IdentityServer - ConfigurationDbContext でのクロスコンテキストトランザクション
&lt;/h3&gt;

&lt;h4&gt;
  
  
  ConfigurationDbContext を使ってクロスコンテキストトランザクションを処理するには？
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F980%2F1%2AW94KJYyivaOCXCRJEo-gqA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F980%2F1%2AW94KJYyivaOCXCRJEo-gqA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;IdentityServer とは？&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;IdentityServer is a free, open source OpenID Connect and OAuth 2.0 framework for ASP.NET Core. Founded and maintained by Dominick Baier and Brock Allen, IdentityServer4 incorporates all the protocol implementations and extensibility points needed to integrate token-based authentication, single-sign-on and API access control in your applications.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;詳細はこちらのリンク↓↓↓&lt;/p&gt;

&lt;p&gt;&lt;a href="https://identityserver4.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;Welcome to IdentityServer4 - IdentityServer4 1.0.0 documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;IdentityServer4 の構成データ (Configuration Data) を EF Core を使って DB に保存することはできます。構成データは「&lt;a href="http://docs.identityserver.io/en/latest/intro/terminology.html#resources" rel="noopener noreferrer"&gt;リソース&lt;/a&gt;」と「&lt;a href="http://docs.identityserver.io/en/latest/intro/terminology.html#client" rel="noopener noreferrer"&gt;クライアント&lt;/a&gt;」を管理します。&lt;/p&gt;

&lt;p&gt;EF Core での構成データの詳細についてはこちら↓↓↓&lt;/p&gt;

&lt;p&gt;&lt;a href="http://docs.identityserver.io/en/latest/quickstarts/7_entity_framework.html" rel="noopener noreferrer"&gt;Using EntityFramework Core for configuration and operational data - IdentityServer4 1.0.0 documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;本題に入ります。&lt;/p&gt;

&lt;p&gt;例えば、ビジネスルールのニーズで、アプリケーションの DB Context でデータを追加する必要があり、それと同時にクライアントを追加する必要があるとします。つまり、セットで追加で処理する必要があります。&lt;/p&gt;

&lt;p&gt;クライアントのクラスの定義は &lt;a href="https://github.com/IdentityServer/IdentityServer4/blob/8f5a4ed926c5c76bf76d7397fae3ce2f4795fd74/src/EntityFramework.Storage/src/DbContexts/ConfigurationDbContext.cs" rel="noopener noreferrer"&gt;ConfigurationDbContext&lt;/a&gt; に存在します。ctor の定義はこんな感じ：&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="nf"&gt;ConfigurationDbContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DbContextOptions&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TContext&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;,&lt;/span&gt; &lt;span class="n"&gt;ConfigurationStoreOptions&lt;/span&gt; &lt;span class="n"&gt;storeOptions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;この ConfigurationDbContext は IdentityServer のもので、アプリケーションの DB Context と異なるため、それぞれを dbContext.SaveChanges() （あるいは await dbContext.SaveChangesAsync() ）で処理すると、仮に例外が発生した場合に整合性がとれなくなってしまいます。&lt;/p&gt;

&lt;p&gt;EF Core でクロスコンテキストトランザクションはサポートされていますので、実現可能です。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/ef/core/saving/transactions#cross-context-transaction-relational-databases-only" rel="noopener noreferrer"&gt;Transactions - EF Core&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;条件としては、&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sharing a DbConnection requires the ability to pass a connection into a context when constructing it.&lt;/p&gt;

&lt;p&gt;The easiest way to allow DbConnection to be externally provided, is to stop using the DbContext.OnConfiguring method to configure the context and externally create DbContextOptions and pass them to the context constructor.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;そして、&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;DbContextOptionsBuilder is the API you used in DbContext.OnConfiguring to configure the context, you are now going to use it externally to create DbContextOptions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;だそうです。&lt;/p&gt;

&lt;p&gt;簡単そうですね！&lt;/p&gt;

&lt;p&gt;サンプルコードはこんな感じで DbContextOptions を生成します。&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;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DbContextOptionsBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BloggingContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&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="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SqlConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectionString&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;それを ConfigurationDbContext ctor に渡せばいいよね～！！と喜ぶのも束の間・・・&lt;/p&gt;

&lt;p&gt;ctor の2番目のパラメータって、 ConfigurationStoreOptions を渡しますよね。DI でこれを気にする必要がなく、やってくれていますので、正しいパラメータはわかりません。。。適当に渡してみてエラーが発生します。デバッグとかで少し時間があればできそうですが、簡単な方法でやりたいです！&lt;br&gt;&lt;br&gt;
そういえば、アプリケーションの DB Context って我々が自由に触れるので、まずそれを使いましょう！ctor は DbContextOptions を渡せるようにします。&lt;/p&gt;

&lt;p&gt;こちらの&lt;a href="https://docs.microsoft.com/en-us/ef/core/saving/transactions#share-connection-and-transaction" rel="noopener noreferrer"&gt;サンプル&lt;/a&gt;で話しますと、 context1 は ConfigurationDbContext に例えて、それをそのまま DI からのインスタンスを使い、14行目の：&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;using&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;context2&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;BloggingContext&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;をこんな感じで context1 の DB コネクションを context2 と共有させます↓&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;using&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;context2&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;ApplicationDbContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DbContextOptionsBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ApplicationDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&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;context1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetDbConnection&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;はい、これでシンプルで問題解決！&lt;/p&gt;

</description>
      <category>identityserver4</category>
      <category>aspnetcore</category>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
