2015-09-13 20 views
9

Die Schnittstelle IAsyncStateMachine kann nur vom Compiler verwendet werden und wird beim Generieren der Statusmaschine für asynchrone Methoden verwendet. Schnittstelle hat SetMachineState - konfiguriert die State Machine mit einem Heap-allokierten Replikat (von msdn).Was ist der Zweck von IAsyncStateMachine.SetStateMachine?

verwendete ich ILSpy Code zu dekompilieren und entdecken Zustandsmaschine erzeugt und erwähnt, dass die Umsetzung von SetMachineState Funktion immer leer ist, wie diese

[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 
    } 
} 

Eine weitere Sache, erzeugt die Zustandsmaschine ist ein class kein struct wie angegeben überall.

Also, die Frage ist: Was der Zweck der SetStateMachine Funktion von IAsyncStateMachine Schnittstelle, wo wird es verwendet?

Original-Asynchron-Funktion:

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

Was ist der Async-Code, den Sie benutzt haben, um * dies zu dekompilieren? Höchstwahrscheinlich hatten Sie gerade keine Bindung – Carsten

+0

Original async Funktion hinzugefügt –

+1

yep - Ich denke, Sie brauchen keine State-Maschine dafür - denken Sie daran: Sie können auch 'tasḱ direkt zurückgeben und der Compiler könnte dies wissen- Fügen Sie mindestens eine weitere asynchrone Funktion/Aufgabe hinzu und versuchen Sie es erneut – Carsten

Antwort

10

Dies geschieht, weil Sie bei einem debug bauen und kein release eine suchen.

Die State-Machine zu einer Struktur machen ist eine Compiler-Optimierung. Es ermöglicht nicht, Speicher zuzuweisen, wenn das Erwartete bereits abgeschlossen ist, wenn es erwartet wird. Diese Optimierung ist beim Debuggen nicht erforderlich und macht die Implementierung von Debugging-Funktionen in Visual Studio schwieriger.

Wenn Sie auf dem gleichen Code in release kompilierte sehen die Zustandsmaschine wird in der Tat eine Struktur sein, und die SetStateMachine Methode nicht leer sein, da dies die Methode ist, dass die Zustandsmaschine aus dem Stapel auf die Halde bewegt:

[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); 
    } 
}