可以内联异步函数吗?

tal*_*kol 6 .net c# optimization asynchronous async-await

内联函数是一种编译器优化,它将函数调用站点替换为被调用者的主体.常规C#函数支持此优化.

在C#5.0 中支持async-await模式的异步函数有一个特殊的声明,它涉及async修饰符和包装返回值Task<>.

异步函数也可以内联吗?

例:

假设我有这些功能:

private async Task<int> CalleeAsync() {
    return await SomeOperationAsync();
}

private async Task<int> CallerAsync() {
    return await CalleeAsync();
}
Run Code Online (Sandbox Code Playgroud)

他们可以优化为:

private async Task<int> CallerAsync() {
    return await SomeOperationAsync();
}
Run Code Online (Sandbox Code Playgroud)

额外信用:

如果支持,谁可以决定内联什么?编译器?JIT?我?

如果它不受支持,我应该担心这个并避免过多的包装我有时会添加以便于阅读吗?

xan*_*tos 4

考虑到 引起的转换的复杂性async/await,我不认为代码是内联的:async/await导致您的方法在隐藏类中进行转换,并且您的代码变成状态机,代码的各个部分变成不同的状态。

举个例子,一个简单的方法CalleeAsync()被转换成一个怪物,比如:

[CompilerGenerated]
private sealed class <CalleeAsync>d__2
{
    private int <>1__state;
    private bool $__disposing;
    public System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> $builder;
    public Action <>t__MoveNextDelegate;
    public Program <>4__this;
    private TaskAwaiter<int> <a1>t__$await4;
    public void MoveNext()
    {
        int result2;
        System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> asyncTaskMethodBuilder;
        try
        {
            int num = this.<>1__state;
            if (num != 1)
            {
                if (this.<>1__state == -1)
                {
                    return;
                }
                this.<a1>t__$await4 = this.<>4__this.SomeOperationAsync().GetAwaiter<int>();
                if (!this.<a1>t__$await4.IsCompleted)
                {
                    this.<>1__state = 1;
                    this.<a1>t__$await4.OnCompleted(this.<>t__MoveNextDelegate);
                    return;
                }
            }
            else
            {
                this.<>1__state = 0;
            }
            int result = this.<a1>t__$await4.GetResult();
            this.<a1>t__$await4 = default(TaskAwaiter<int>);
            result2 = result;
        }
        catch (Exception exception)
        {
            this.<>1__state = -1;
            asyncTaskMethodBuilder = this.$builder;
            asyncTaskMethodBuilder.SetException(exception);
            return;
        }
        this.<>1__state = -1;
        asyncTaskMethodBuilder = this.$builder;
        asyncTaskMethodBuilder.SetResult(result2);
    }
    [DebuggerHidden]
    public void Dispose()
    {
        this.$__disposing = true;
        this.MoveNext();
        this.<>1__state = -1;
    }
    [DebuggerHidden]
    public <CalleeAsync>d__2(int <>1__state)
    {
        this.<>1__state = <>1__state;
    }
}
Run Code Online (Sandbox Code Playgroud)

(请注意,在这台计算机上,我仍然拥有带有 Async CTP 的 Visual Studio 2010,而使用 .NET 4.5 时,生成的代码可能会有所不同)。

你认为这样的东西是内联的吗?

  • 好吧,如果我必须遵循我的想法,我想我会说大多数编译器优化都是不可能的:)如果编译器在编译到这个状态机怪物之前尝试内联怎么办?我可以看到这种情况发生在预处理器级别(如果存在的话),尽管我真的不知道我在说什么 (2认同)