20.01/30C#使う人って全然外部プロセス呼び出して処理ってしないよね。いうのは、Windowsがなんかそういうのを避ける雰囲気だから、というのもあるのですが、ともあれ実際、可能な限り避けるどころか絶対避ける、ぐらいの勢いがあります。ライブラリになってないと嫌だ、断固拒否、みたいな。最近はLinuxでもばっちし動くのでそういう傾向もどうかなー、と思いつつ。避けるというのはOSの違いというのもありそうですが、もう一つはそもそも外部プロセスの呼び出しが死ぬほど面倒くさい。ProcessとProcessStartInfoを使ってどうこうするのですが、異常に面倒くさい。理想的にはシェルで書くように一行でコマンドと引数繋げたstringを投げておしまい、と行きたいのですが、全然そうなってない。呼び出すだけでも面倒くさいうぇに、StdOutのリダイレクトとかをやると更に面倒くさい。非同期でStdOutを読み込むとかすると絶望的に面倒くさい、うえに罠だらけでヤバい。この辺の辛さは非同期外部プロセス起動で標準出力を受け取る際の注意点という記事でしっかり紹介されてますが、実際これを正しくハンドリングするのは難儀です。foreachするだけで受け取れて」「ExitCodeやStdErrorなども適切にハンドリングする」ライブラリを作りました。8.0万歳!実際これ、普通のProcessで書くと中々のコード量になります。process.WaitForExit();}↑のものでも少し簡略化しているぐらいなので、それぞれより正確にハンドリングしようとすると相当、厳しい、です......。foreachの良いところは例外処理にtry-catchがそのまま使えること、というわけで、ExitCodeが0以外(或いはStdErrorを受信した場合)には、ProcessErrorExceptionが飛んでくるという仕様になっています。Console.WriteLine(ex.ToString());}WaitForExit的に、同期待ちして結果を全部取りたいという場合は、ToTaskが使えます。--info").ToTask();キャンセルに関しては非同期ストリームのWithCancellationがそのまま使えます。キャンセル時にプロセスが残っている場合はキャンセルと共にKillして確実に殺します。Console.WriteLine(item);}タイムアウトは、CancellationTokenSource自体が時間と共に発火というオプションがあるので、それを使えます。}}また、ProcessX.StartAsyncのオーバーロードとして、作業ディレクトリや環境変数、エンコードを設定できるものも用意しているので、ほとんどのことは問題なく実装できるはずです。default)System.Threading.Channels今回、ProcessのイベントとAsyncEnumeratorとのデータの橋渡しにはSystem.Threading.Channelsを使っています。System.Threading.Channels、或いは日本語だとSystem.Threading.Channelsを使うを読むと良いでしょう。プロデューサー・コンシューマーパターンのためのライブラリなのですが、めっちゃ便利です。シンプルなインターフェイス(ちょっと弄ってれば使い方を理解できる)かつasync/awaitビリティがめっちゃ高い設計になっていて、今まで書きづらかったものがサクッと書けるようになりました。これはめちゃくちゃ良いライブラリなのでみんな使いましょう。好きじゃなくて全然使うことはなかったのですが、Channelsは良い。1.0世代(10年前!)に設計されたライブラリなのでしょうがないという側面もありつつも、やはり現代は現代なので、ちゃんと現代流に設計したものを再度提供してあげる価値はあるでしょう。設計技法も言語自体も、遥かに進化しているので、ちゃんとしたアップデートは必要です。した隙間産業だけど、C#に今までなくて面倒で、でもそれが一気に解消して超絶便利に、というのはConsoleAppFrameworkに通じるものがあります。C#の面倒と思えるところを片っ端から潰して超絶便利言語にしていく、ことを目指して引き続きどしどし開発していきます。いうわけで是非使ってみてください。(01/3103:04)なるほど!読めたほうが良いと思うので、StartReadBinaryAsyncというのを足してみました。ProcessX.StartReadBinaryAsync($”...”);`という感じですね。