2015-09-13 6 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

добавлена ​​оригинальная функция async –

+1

yep - Я думаю, вам не нужна какая-либо государственная машина для этого - подумайте об этом: вы можете просто вернуть 'tasḱ' напрямую, и компилятор может это знать, добавьте хотя бы еще одну функцию/задачу async и повторите попытку – Carsten

ответ

10

Это происходит потому, что вы смотрите на debug строят и не release один.

Создание государственной машины struct является оптимизацией компилятора. Это позволяет не выделять память, когда ожидаемый уже завершен, когда его ждут. Эта оптимизация не требуется во время отладки, и это упрощает реализацию функций отладки в 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); 
    } 
} 
Смежные вопросы