2015-09-13 21 views
9

L'interfaccia IAsyncStateMachine può essere utilizzata solo dal compilatore e viene utilizzata nella generazione della macchina di stato per i metodi asincroni. L'interfaccia ha SetMachineState - configura la macchina di stato con una replica allocata su heap (da msdn).Qual è lo scopo di IAsyncStateMachine.SetStateMachine?

Ho usato ILSpy per decompilare codice e scoprire generato macchina a stati e dicono che l'attuazione di SetMachineState funzione è sempre vuota, simili

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

Un'altra cosa, macchina a stati generato è un non class una struct come indicato ovunque.

Quindi, la domanda è: qual è lo scopo della funzione SetStateMachine dell'interfaccia IAsyncStateMachine, dove viene utilizzata?

funzione asincrona originale:

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

qual è il codice asincrono usato per * decompilare * questo? Molto probabilmente non hai avuto alcun legame – Carsten

+0

aggiunto la funzione asincrona originale –

+1

sì - Penso che non ti serva alcuna macchina di stato per quello - pensaci: puoi anche restituire 'tasḱ' direttamente e il compilatore potrebbe sapere questo- aggiungi almeno un'altra funzione asincrona/task e riprova – Carsten

risposta

10

Questo accade perché si sta guardando un accumulo debug e non un release uno.

Rendere la macchina di stato una struttura è un'ottimizzazione del compilatore. Permette di non allocare memoria quando l'attendibile è già completato quando è atteso. Questa ottimizzazione non è necessaria durante il debug e rende più difficile l'implementazione delle funzionalità di debug in Visual Studio.

Se si guarda lo stesso codice compilato nel release stato macchina sarà davvero una struct e il metodo SetStateMachine non sarà vuota come questo è il metodo che muove la macchina dello Stato dalla pila al mucchio:

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