Причина такого "шипения" заключается в том, что компилятору нужно выполнить лот работы, чтобы представить задачу, которая работает всеми ожидаемыми правильными способами, которые вы можете увидеть по компилирование и декомпиляция
Task.FromResult
чище, но может иметь дополнительные издержки - в IIRC есть несколько сценариев, в которых Task.FromResult
может работать эффективно (возвращая один и тот же объект каждый раз), но я бы не стал полагаться на него.
Существует 2 прагматичных надежных подхода:
- возвращает повторно использованный статический
Task<bool>
результат каждый раз
- используйте
ValueTask<bool>
- что кажется идеальным здесь, если вы возвращаетесь синхронно большую часть времени
1021 * т.е. *
private readonly static Task<bool> s_False = Task.FromResult(false);
public Task<bool> Contains(string key, string scope)
{
return s_False ;
}
или
public ValueTask<bool> Contains(string key, string scope)
{
return new ValueTask<bool>(false);
}
Примечание: второе из них может быть невозможно в этом случае, так как вы не определили интерфейс. Но: если вы когда-либо проектируете интерфейс, который должен разрешать асинхронное использование, но который на самом деле может быть синхронизирован: рассмотрите возможность использования ValueTask<T>
в качестве типа обмена, а не Task<T>
.
Сгенерированный C # из:
public async System.Threading.Tasks.Task<bool> Contains(string key, string scope)
{
return false;
}
это что-то вроде:
[StructLayout(LayoutKind.Auto)]
[CompilerGenerated]
private struct <Contains>d__0 : IAsyncStateMachine
{
public int <>1__state;
public AsyncTaskMethodBuilder<bool> <>t__builder;
private void MoveNext()
{
bool result;
try
{
result = false;
}
catch (Exception exception)
{
<>1__state = -2;
<>t__builder.SetException(exception);
return;
}
<>1__state = -2;
<>t__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)
{
<>t__builder.SetStateMachine(stateMachine);
}
void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
{
//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
this.SetStateMachine(stateMachine);
}
}
[AsyncStateMachine(typeof(<Contains>d__0))]
public Task<bool> Contains(string key, string scope)
{
<Contains>d__0 stateMachine = default(<Contains>d__0);
stateMachine.<>t__builder = AsyncTaskMethodBuilder<bool>.Create();
stateMachine.<>1__state = -1;
AsyncTaskMethodBuilder<bool> <>t__builder = stateMachine.<>t__builder;
<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}