[解決済み] なぜRoslynでは非同期ステートマシンはクラス(構造体)ではないのですか?
質問
この非常に単純な非同期メソッドについて考えてみましょう。
static async Task myMethodAsync()
{
await Task.Delay(500);
}
これをVS2013(Roslynコンパイラ以前)でコンパイルすると、生成されるステートマシンはstructになります。
private struct <myMethodAsync>d__0 : IAsyncStateMachine
{
...
void IAsyncStateMachine.MoveNext()
{
...
}
}
VS2015(Roslyn)でコンパイルすると、生成されたコードはこのようになります。
private sealed class <myMethodAsync>d__1 : IAsyncStateMachine
{
...
void IAsyncStateMachine.MoveNext()
{
...
}
}
ご覧の通り、Roslynは(構造体ではなく)クラスを生成します。私の記憶が正しければ、古いコンパイラ (CTP2012 だと思います) の非同期/待機サポートの最初の実装もクラスを生成していましたが、パフォーマンス上の理由から構造体に変更されたようです。(場合によっては、箱詰めやヒープ割り当てを完全に回避できることもあります...) (参照 この )
なぜこれがRoslynで再び変更されたのか、ご存知の方はいらっしゃいますか?(私はこれに関して何の問題もありませんし、この変更が透過的でどのコードの動作も変えないことも知っています。)
編集します。
Damien_The_Unbeliever の回答 (およびソースコード :) がすべてを説明していると思います。Roslyn の記述された動作は、デバッグビルドにのみ適用されます (そして、これはコメントにある CLR の制限のために必要なのです)。Releaseでは、構造体も生成されます(その利点はすべてありますが・・・)。これは、EditとContinueの両方をサポートし、実稼働時のパフォーマンスを向上させる、非常に賢いソリューションのように思えます。興味深い内容でした。参加してくれたみなさん、ありがとうございました。
どのように解決するのですか?
私は予知していませんでしたが、最近のRoslynはオープンソースなので、コードを漁って説明することができます。
そして、ここでも の 60 行目、AsyncRewriter の を見つけることができます。
// The CLR doesn't support adding fields to structs, so in order to enable EnC in an async method we need to generate a class.
var typeKind = compilationState.Compilation.Options.EnableEditAndContinue ? TypeKind.Class : TypeKind.Struct;
このように
struct
を使うことにも魅力がありますが、大きな利点は
編集と続行
の中で動作させることができるようになりました。
async
メソッドで動作するようにすることが、より良い選択肢として選ばれたのは明らかです。
関連
-
[解決済み] [Solved] 1つ以上のエンティティで検証に失敗しました。詳細は'EntityValidationErrors'プロパティを参照してください [重複]。
-
[解決済み】ASP.NET Core Dependency Injectionのエラーです。アクティブ化しようとしているときに、タイプのサービスを解決できません。
-
[解決済み】「入力文字列が正しい形式ではありませんでした」エラーの解決方法は?[重複しています]。
-
[解決済み】C# ASP.NET使用時に「WebClientのリクエスト中に例外が発生しました。
-
[解決済み】WPFでXamlファイルにコメントを追加する方法は?
-
[解決済み】ランダムなブーリアンを生成する最速の方法
-
[解決済み] CSS Flexboxで、"justify-items "と "justify-self "プロパティはなぜないのですか?
-
[解決済み] ミュータブル構造体はなぜ "悪 "なのか?
-
[解決済み】非同期処理の待ち時間、Wait()でプログラムがフリーズする原因はここにある
-
[解決済み】C# 5 非同期 CTP:生成されたコードで EndAwait 呼び出しの前に内部の "state" が 0 に設定されるのはなぜですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] エンティティタイプ ApplicationUser は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み] メンバー '<メンバー名>' にインスタンス参照でアクセスできない
-
[解決済み】C#におけるtypedefの等価性
-
[解決済み】C#はJavaのcharAt()と同等?)
-
[解決済み】取り消せないメンバはメソッドのように使えない?
-
[解決済み】WSACancelBlockingCallの例外について
-
[解決済み】2年前のMSDateを把握する【クローズド
-
[解決済み】Unityでゲームオブジェクトのすべての子をループスルーして破壊する方法?
-
[解決済み】ユーザー設定値を別のユーザー設定値で設定する
-
[解決済み】デバッグビルドとリリースビルドの性能差について