从该方法提早返回时,异步/等待是否会产生额外的费用? [英] Does async/await have an extra cost associated when returning early from the method?

查看:64
本文介绍了从该方法提早返回时,异步/等待是否会产生额外的费用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与同步方法相比,从方法中早返回时,异步/等待是否会产生额外的相关费用?

Does async/await have an extra cost associated when returning early from the method compared to the synchronous method?

以这些示例为例:

public async Task<bool> TryDoSomethingAsync()
{
    if ( Is99PercentOfTheCases() )
        return false;  // does this path...

    await DoSomethingAsync();

    return true;
}

// versus 

public bool TryDoSomething()
{
    if ( Is99PercentOfTheCases() )
        return false; // ...have the same cost as this path?

    DoSomething();

    return true;
}

我知道async/await会带来额外的费用,因此您需要注意紧密的循环-请参见

I know async/await has an extra cost associated and therefore you need to be careful around tight loops - see i.e. https://www.red-gate.com/simple-talk/dotnet/net-framework/the-overhead-of-asyncawait-in-net-4-5/

但是,这笔费用何时发生?

But when is this cost occurring?

  • 将方法标记为异步时是吗?
  • 需要等待的时间吗?
  • 还是与任务返回类型有关?
  • 特别是:对于异步方法提早返回时,性能是否还会降低?

最后,最好总是描述特定的案例,但是我对背后的理论很感兴趣.

In the end it's always best to profile specific cases, but I'm interested in the theory behind it.

推荐答案

TryDoSomethingAsync 中的代码被编译器转换为IL代码,或多或少与以下代码等效:

The code in your TryDoSomethingAsync get converted by the compiler to IL code that is, more or less, the equivalent of this:

public Task<bool> TryDoSomethingAsync()
{
    TryDoSomethingAsyncStateMachine stateMachine = new TryDoSomethingAsyncStateMachine();
    stateMachine._this = this;
    stateMachine._builder = AsyncTaskMethodBuilder<bool>.Create();
    stateMachine._state = -1;
    AsyncTaskMethodBuilder<bool> _builder = stateMachine._builder;
    _builder.Start(ref stateMachine);
    return stateMachine._builder.Task;
}

private sealed class TryDoSomethingAsyncStateMachine : IAsyncStateMachine
{
    public int _state;
    public AsyncTaskMethodBuilder<bool> _builder;
    public UserQuery _this;

    private TaskAwaiter _awaiter;

    private void MoveNext()
    {
        int num = _state;
        bool result;
        try
        {
            TaskAwaiter awaiter;
            if (num == 0)
            {
                awaiter = _awaiter;
                _awaiter = default(TaskAwaiter);
                num = (_state = -1);
                goto IL_0080;
            }
            if (!_this.Is99PercentOfTheCases())
            {
                awaiter = _this.DoSomethingAsync().GetAwaiter();
                if (!awaiter.IsCompleted)
                {
                    num = (_state = 0);
                    _awaiter = awaiter;
                    TryDoSomethingAsyncStateMachine stateMachine = this;
                    _builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
                    return;
                }
                goto IL_0080;
            }
            result = false;
            goto end_IL_0007;
        IL_0080:
            awaiter.GetResult();
            result = true;
        end_IL_0007:;
        }
        catch (Exception exception)
        {
            _state = -2;
            _builder.SetException(exception);
            return;
        }
        _state = -2;
        _builder.SetResult(result);
    }

    void IAsyncStateMachine.MoveNext()
    {
        //ILSpy generated this explicit interface implementation from .override directive in MoveNext
        this.MoveNext();
    }

    [DebuggerHidden]
    private void SetStateMachine(IAsyncStateMachine stateMachine)
    {
    }

    void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
    {
        //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
        this.SetStateMachine(stateMachine);
    }
}

运行的代码比普通的异步方法还要多.

There is considerable more code that is run that the plain async method.

但是,运行 Is99PercentOfTheCases()的代码仍然相当轻巧.这样会很快,但不会比非异步方法快.

However, the code that runs the Is99PercentOfTheCases() is still fairly light. It will be quick, but not as quick as the non-async method.

这篇关于从该方法提早返回时,异步/等待是否会产生额外的费用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆