--- lang: ja-jp breaks: true --- # C# `Visual Studio 2022` を使用した .NET/C# における `sync over async` 問題 解決のベストプラクティス 2021-11-20 > Visual Studio 2022を使用した.NET/C#におけるsync over async問題の修正 > https://youtu.be/Yvt83lPRCys > {%youtube Yvt83lPRCys %} ## ダメな例 `Result` により、結果的に二つのスレッドを占有し 通常の同期操作よりもパフォーマンスを悪化させる。 ![](https://i.imgur.com/TFf5hO8.png) 以下も同じこと。 ![](https://i.imgur.com/OonSH6W.png) ## 正しくは、`async` `await` を使って書きましょう ![](https://i.imgur.com/p4tbl1T.png) :::info パフォーマンスカウンタで、`ThreadPool Queue Length` `ThreadPool Thread Count` を確認することが大事。正しくコーディングされている場合は通常運用の状態で、`ThreadPool Queue Length` は `0` 近くになるはず。 ![](https://i.imgur.com/oyOAw1h.png) ::: ```shell= dotnet tool install --global dotnet-counters ``` ```shell= dotnet-counters ps ``` コマンドラインから実行 ```shell= dotnet-counters monitor -p 52760 ``` プログラムから呼び出す ```csharp= static async Task Main(string[] args) { Console.WriteLine("Hello World!"); Task _ = DotnetCountersMonitorAsync(); Console.ReadLine(); } static async Task DotnetCountersMonitorAsync( CancellationTokenSource cancellationTokenSource = null ) { using (var p = System.Diagnostics.Process.GetCurrentProcess()) { int processId = p.Id; var path = @"dotnet-counters"; string arguments = $@"monitor -p {processId.ToString()}"; { var psi = new System.Diagnostics.ProcessStartInfo(path, arguments) { CreateNoWindow = false, UseShellExecute = true }; using (var process = System.Diagnostics.Process.Start(psi)) { if (cancellationTokenSource != null) { await process.WaitForExitAsync(cancellationTokenSource.Token) .ConfigureAwait(false); } else { await process.WaitForExitAsync() .ConfigureAwait(false); } process.CloseMainWindow(); process.Close(); } } } } ``` ## `Microsoft.VisualStudio.Threading.Analyzers` が使える スレッドに関する警告をVisualStudio上に表示してくれる。 ![](https://i.imgur.com/XoY9n6z.png) `*.csproj` ```xml= <ItemGroup> <PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.0.64"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> </ItemGroup> ``` ###### tags: `C#` `async` `await` `非同期` `パフォーマンス` `Visual Studio 2022` `ThreadPool Queue Length` `ThreadPool Thread Count`