2015-09-13 8 views
9

インターフェイスIAsyncStateMachineは、コンパイラによってのみ使用でき、非同期メソッド用のステートマシンの生成に使用されます。インターフェイスはSetMachineStateです - (msdnからの)ヒープ割り当てされたレプリカでステートマシンを構成します。IAsyncStateMachine.SetStateMachineの目的は何ですか?

私は、コードをコンパイルするためにILSpyを使用して生成されたステート・マシンを発見し、SetMachineState機能の実装は、この

[CompilerGenerated] 
private sealed class <GetResult>d__1 : IAsyncStateMachine 
{ 
    //some fields to hold state 

    void IAsyncStateMachine.MoveNext() 
    { ... } 

    [DebuggerHidden] 
    void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) 
    { 
     //Method is empty 
    } 
} 

もう一つのように、常に空であることを言及し、生成されたステートマシンが述べたようにclassないstructですどこにでも。

したがって、質問は次のとおりです。の機能の目的はどこですか?

オリジナル非同期機能:あなたはdebugビルドではなくrelease 1を見ているので

private static async Task<int> GetResult() 
{ 
    var task = GetSomeData(); 
    DoSomeWork(); 
    return await task; 
} 
+1

*これを逆コンパイルするために使用した非同期コードは何ですか?ほとんどの場合バインドされていない可能性があります – Carsten

+0

オリジナルの非同期関数が追加されました –

+1

これは状態マシンが必要ないと思います:少なくとももう1つの非同期関数/タスクを追加して、もう一度 – Carsten

答えて

10

この問題が発生しました。

ステートマシンを構造化することは、コンパイラの最適化です。それは、待たれているときに待ち時間が既に完了しているときにメモリを割り当てないようにする。その最適化はデバッグ中には必要なく、Visual Studioでのデバッグ機能の実装がより困難になります。

あなたは同じコードを見ればreleaseでコンパイルされた状態マシンが実際に構造体になり、これはヒープにスタックからステート・マシンを移動する方法であるとしてSetStateMachine方法が空になりません。

[CompilerGenerated] 
[StructLayout(LayoutKind.Auto)] 
private struct <GetResult>d__1 : IAsyncStateMachine 
{ 
    public AsyncTaskMethodBuilder<int> <>t__builder; 
    ... 

    [DebuggerHidden] 
    void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) 
    { 
     this.<>t__builder.SetStateMachine(stateMachine); 
    } 
} 
関連する問題