2015-09-13 70 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的規定到處。

那麼,問題是:SetStateMachine功能的目的是什麼IAsyncStateMachine接口,它在哪裏使用?

原始異步功能:

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

什麼是異步代碼你用*反編譯*這個?很可能你只是沒有綁定 – Carsten

+0

添加了原始的異步函數 –

+1

是的 - 我認爲你不需要任何狀態機 - 想一想:你可以直接返回'tasḱ'並且編譯器可能知道這個 - 添加至少一個異步函數/任務,然後再次嘗試 – Carsten

回答

10

這是因爲你正在尋找一個debug構建,而不是release一個。

使狀態機構成一個結構體是一個編譯器優化。當等待時間已經完成時,它不能分配內存。這種優化在調試時不是必須的,它使得在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); 
    } 
}