まずは、優しい言葉をありがとうございます。それは確かに素晴らしい機能であり、私はその一部であったことを嬉しく思います。
すべてのコードがゆっくりと非同期になっている場合は、デフォルトですべて非同期にしてみませんか?
まあ、あなたは誇張しています。すべてのコードが非同期になっていません。2つの「プレーン」整数を一緒に追加すると、結果を待つことはありません。次の2つの追加すると、将来の整数を第三取得するために一緒に将来の整数をそれが何だから-Task<int>
で、それはあなたがしているが、将来的にへのアクセスを得ようとしていることを整数だ-もちろん、あなたはおそらく、結果を待っていることでしょう。
すべてを非同期にしない主な理由は、async / awaitの目的が、レイテンシの高い操作が多い世界でコードを簡単に記述できるようにするためです。あなたの業務の大半はありません、それはパフォーマンスを取るためにどんな意味をなすことレイテンシーその緩和するに当たらないので、長い待ち時間。むしろ、操作の重要ないくつかは高レイテンシであり、それらの操作はコード全体でゾンビによる非同期の侵入を引き起こしています。
パフォーマンスが唯一の問題である場合、確かにいくつかの巧妙な最適化により、不要なオーバーヘッドが自動的に削除されます。
理論的には、理論と実践は似ています。実際には、そうではありません。
この種類の変換に対して3つのポイントを与え、その後に最適化パスを示します。
最初のポイントは再びです:C#/ VB / F#の非同期は本質的に継続渡しの制限された形式です。関数型言語コミュニティにおける膨大な量の研究が、継続渡しスタイルを多用するコードを最適化する方法を特定する方法を見つけることに費やされています。コンパイラー・チームは、「非同期」がデフォルトであり、非非同期メソッドを識別して非同期化する必要があった世界で、非常によく似た問題を解決する必要があるでしょう。C#チームは、オープンリサーチの問題に取り組むことにはあまり興味がないので、それは、そこでの大きなポイントです。
反対の2番目のポイントは、C#には、この種の最適化を扱いやすくする「参照透過性」のレベルがないことです。「参照透過性」とは、式の値が評価されるときに依存しないという特性を意味します。のような式2 + 2
は参照透過的です。必要に応じてコンパイル時に評価を行うか、実行時まで延期して同じ答えを得ることができます。しかし、xとyは時間とともに変化する可能性があるx+y
ため、などの式は時間内に移動できません。
非同期では、副作用がいつ発生するかを推測することがはるかに困難になります。非同期にする前に、あなたが言ったなら:
M();
N();
そして、M()
したvoid M() { Q(); R(); }
、とN()
したvoid N() { S(); T(); }
、とR
してS
農産物の副作用、あなたはRの副作用がSの副作用の前に起こることを知っています。しかしasync void M() { await Q(); R(); }
、突然それがなくなった場合、がR()
発生する前か後に発生するかどうかは保証されませんS()
(もちろんM()
、待機する場合を除きますが、もちろん、Task
待機する必要はありませんN()
)。
ここで、オプティマイザが非同期化するために管理するものを除いて、プログラム内のすべてのコードに、どのような副作用が発生するかを認識しないというこの特性が当てはまると想像してください。基本的に、どの式がどの順序で評価されるのかもう手がかりがありません。つまり、すべての式は参照透過である必要があり、C#のような言語では難しいです。
反対の3番目のポイントは、「なぜ非同期がそれほど特別なのか」と尋ねる必要があることです。すべての操作が実際にaであるTask<T>
必要があると主張する場合は、「なぜしないのLazy<T>
か」という質問に答えられる必要があります。または「どうしてNullable<T>
ですか?」または「どうしてIEnumerable<T>
ですか?」簡単にできるからです。すべての操作がnullableに引き上げられるのはなぜでしょうか?または、すべての操作が遅延計算され、結果が後でキャッシュされるか、すべての操作の結果が単一の値ではなく一連の値になります。次に、「ああ、これは決してnullであってはならないので、私はより良いコードを生成できる」などとわかっている状況を最適化する必要があります。
重要Task<T>
なのは、これだけの作業を保証するのに実際に特別なのかどうかは、私には明らかではありません。
これらの種類のものに興味がある場合は、Haskellのような関数型言語を調査することをお勧めします。Haskellは、参照の透過性が非常に高く、あらゆる種類の異常な評価を可能にし、自動キャッシュを実行します。Haskellはまた、私が言及した種類の「モナディックリフティング」の型システムをはるかに強力にサポートしています。