Sig*_*hol 3 c# asynchronous async-await
请考虑以下界面:
public interface IProvider
{
Task<bool> Contains(string key);
}
Run Code Online (Sandbox Code Playgroud)
这是实现满足Visual Studio
public Task<bool> Contains(string key)
{
return Task.FromResult(false);
}
Run Code Online (Sandbox Code Playgroud)
这种实现方便编写,似乎可以实现同样的目的:
public async Task<bool> Contains(string key)
{
return false;
}
Run Code Online (Sandbox Code Playgroud)
然而,Visual Studio引发了一种混乱并坚持:
这种异步方法缺少"等待"运算符并将同步运行.考虑使用'await'运算符等待非阻塞API调用,或'await TaskEx.Run(...)'在后台线程上执行CPU绑定工作.
我很乐意忽略这个警告并避免使用Task.FromResult(...).
使用后一种选择会产生任何负面影响吗?
Mar*_*ell 13
其原因"嘘声像适合"是编译器需要做很多工作来呈现,在所有的预期正确的方式在这里工作的任务,你可以看到通过编译和反编译它
Task.FromResult更清洁,但可能仍然有开销 - IIRC有一些场景Task.FromResult可以在这里高效工作(每次返回相同的对象),但我不会依赖它.
有两种实用可靠的方法:
Task<bool>每次都返回一个重用的静态结果ValueTask<bool>- 如果你在很多时候同步返回,这似乎是理想的即
private readonly static Task<bool> s_False = Task.FromResult(false);
public Task<bool> Contains(string key, string scope)
{
return s_False ;
}
Run Code Online (Sandbox Code Playgroud)
要么
public ValueTask<bool> Contains(string key, string scope)
{
return new ValueTask<bool>(false);
}
Run Code Online (Sandbox Code Playgroud)
注意:在这种情况下,第二个可能是不可能的,因为您没有定义接口.但是:如果您正在设计一个需要允许异步使用但实际上可能同步的接口:请考虑使用ValueTask<T>作为交换类型,而不是Task<T>.
生成的C#:
public async System.Threading.Tasks.Task<bool> Contains(string key, string scope)
{
return false;
}
Run Code Online (Sandbox Code Playgroud)
是这样的:
[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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
681 次 |
| 最近记录: |