2015-09-13 33 views
9

Interfejs IAsyncStateMachine może być używany tylko przez kompilator i służy do generowania automatu stanów dla metod asynchronicznych. Interfejs ma SetMachineState - konfiguruje automat stanów z repliką przydzieloną sterty (z msdn).Jaki jest cel IAsyncStateMachine.SetStateMachine?

użyłem ILSpy dekompilować kodu i odkryć generowane machiny państwowej i wspomniał, że realizacja SetMachineState funkcji jest zawsze pusty, jak to

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

Jeszcze jedno, generowane maszyna stanów jest nie classstruct jak stwierdzono wszędzie.

Pytanie brzmi: jaki jest cel funkcji SetStateMachine interfejsu , gdzie jest używany?

Oryginalna funkcja asynchroniczny:

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

jaki jest kod asynchroniczny użyty do * dekompilacji * tego? Najprawdopodobniej po prostu nie miałeś powiązania – Carsten

+0

dodano oryginalną funkcję asynchroniczną –

+1

yep - Myślę, że nie potrzebujesz do tego żadnej maszyny stanowej - pomyśl o tym: równie dobrze możesz zwrócić 'tasḱ' bezpośrednio i kompilator może to wiedzieć- dodaj co najmniej jeszcze jedną asynchroniczną funkcję/zadanie i spróbuj ponownie – Carsten

Odpowiedz

10

Dzieje się tak dlatego, że jesteś patrząc na debug build a nie release jednym.

Tworzenie maszyny stanowej to optymalizacja kompilatora. Umożliwia to nieprzydzielanie pamięci, gdy oczekiwana wartość jest już ukończona w oczekiwaniu. Ta optymalizacja nie jest konieczna podczas debugowania i sprawia, że ​​implementowanie funkcji debugowania w programie Visual Studio jest trudniejsze.

Jeśli spojrzeć na ten sam kod skompilowany w release state-maszyna będzie rzeczywiście być struktura i sposób SetStateMachine nie będzie pusta, ponieważ jest to metoda, która porusza państwowego maszynę ze stosu do sterty:

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