Dir*_*oer 3 c# asynchronous async-await
与同步方法相比,从方法提前返回时 async/await 是否有额外的成本?
以这些例子为例:
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;
}
Run Code Online (Sandbox Code Playgroud)
我知道 async/await 会产生额外的成本,因此您需要注意紧密循环 - 参见即https://www.red-gate.com/simple-talk/dotnet/net-framework/the-overhead-of -asyncawait-in-net-4-5/
但是这个成本什么时候发生?
最后,最好描述特定案例,但我对其背后的理论很感兴趣。
TryDoSomethingAsync编译器将 get 中的代码转换为 IL 代码,或多或少相当于:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
与普通异步方法相比,运行的代码要多得多。
但是,运行 的代码Is99PercentOfTheCases()仍然相当轻量。它会很快,但不如非异步方法快。