web-dev-qa-db-ja.com

非同期性は実装の詳細ではありませんか?

シンプルな、そして偽の—インターフェースを考えてみましょう:

interface ISuperGetter { Super Get(); }
  • 実装はRAMからSuperを取得します。
  • 必要なものをディスクに保存します。
  • さらにもう1つは、リモートHTTP REST JSONサーバーからSuperを初期化するために必要な状態をフェッチできます。
  • 最後の1つは、実際に磁気テープの棚をシークし、いくつかの機械式リーダーに正しいバンドを差し込むロボットアームに命令します。

開発時には、RAMベースの実装が使用される可能性がありますが、ソフトウェアが進化するにつれて、他の実装も開発する必要がある可能性があります。それらがますます増えるにつれてwait-based-sluggish —上記のリストの順に—操作を非同期にする必要性が出てきます...

ここで私が抱えている1つの問題はコードレベルにあります。通常、.NETの非同期性の方法には、async修飾子などの大量のボイラープレートが含まれ、戻り値の型をTaskに変更します。メソッド名にAsyncを追加し、awaitでコードを乱雑にします。

非同期性が.NETに組み込まれている方法で私が抱えている2番目の、そして主要な問題は、インターフェイスも変更する必要があるという事実です。

interface ISuperGetter { Task<Super> GetAsync(); }

さらに、変更の順序は高レベルのポリシーからではなく、低レベルの実装の詳細から来ます!

これは、デフォルトですべてを非同期にすることを奨励しているように見えます "念のため"。

.NETの非同期性は本当にこのように使用することを意図したものですか、それとも私の理解は間違っていますか?異なる方法で構築された他の非同期モデルはありますか?

2
Odepax

それらがますます待機ベースの緩慢なものになると、上記のリストの順に、操作を非同期にする必要性が生じます...

あなたの推論は、「将来の要件は変わる可能性があるので、今それらのために設計しましょう」です。

スマート。しかし、そこで止まらないでください。エラー処理についてはどうですか?確かに、このインターフェイスの一部の実装は例外をスローする可能性がありますが、多分将来的に誰かは、エラー時に呼び出されるデリゲートを必要とします多分将来の誰かが修正する方法を知っているその場での問題。だからと停止しないでください:

interface ISuperGetter { Task<Super> GetAsync(); }

あなたがしたいだろう

interface ISuperGetter { Task<Super> GetAsync(Action onFailure); }

そして、多分将来的に誰かは、一度に複数のスーパーを返すことができるようにしたいと思うでしょう。なぜなら、複数のヒットよりもデータベースにバッチヒットを行う方がはるかに効率的だからです。書く

interface ISuperGetter { Task<IEnumerable<Super>> GetAsync(Action onFailure); }

そしてそうなる。私たちは、将来の人々が一日に何を必要とするかについての物語を作り上げることができ、決して来ないかもしれない一日に備えるためにインターフェースの設計を非常に複雑にします。

YAGNIと呼ばれるこの状況に適用される設計原則があります。あなたはそれを必要としません。 現在およびすぐに予想されるユーザーのニーズを満たすようにインターフェースを設計する必要があります。

.NETの非同期は本当にこのように使用することを意図していますか?

いいえ。非同期ワークフローは、ユーザーの操作に応答したり、リソースを効率的に使用したりする必要があるため、当然ながら非同期を処理するように構築されたプログラムで使用することを目的としています。非同期ワークフローは、事前に高レイテンシであることがわかっている操作から構成される(== --- ==)ことを目的としています。プログラムがこれらの特性と一致しない場合は、非同期用に設計しないでください。含まれている場合は、非同期のプログラムを最初から作成します。

さらに、変更の順序は、高レベルのポリシーからではなく、低レベルの実装の詳細から発生します。

これは重要な誤解です。非同期プログラムは、基本的にアーキテクチャレベルの同期プログラムとは異なります。 非同期プログラムは、すべてのワークフローが「処理中」で部分的に完了している可能性があること、一部が失敗状態である可能性があること、およびワークフロー内のノードがawaitを除いて任意に並べ替えられる可能性があるという概念に基づいて構築する必要があります順序付けを強制するために使用されます

これらの考慮事項は、非同期メソッドがタスクを返すという事実から生じるものではありません。これらは、非同期性が同期計算モデルとは根本的に異なるという事実から生じます。

異なる方法で構築された他の非同期モデルはありますか?

はい。現在のモデルは、はるかに原始的で困難な非同期のモデルから発展し、非同期モデルはさらにより原始的なモデルから発展しました。言っておきますが、非同期Windows 3.1プログラムを書いたことがないひどい音楽を聴いている今日の子供たちは、それがどれほど優れているかわからないので、私の芝生から降りる必要があります。ガベージコレクション、仮想メモリ、フラットメモリ、非協調型マルチタスク、プロセス、またはスレッドを使用せずに、オペレーティングシステムで非同期プログラムを作成することをお勧めします。非同期はハードウェア割り込みハンドラーによって表され、async/await C#で。今日の非同期は、リッチなワークフロートポロジを構築するための強力なツールの理想郷の夢です。

14
Eric Lippert