考虑以下接口(interface):

public interface IProvider
{
    Task<bool> Contains(string key);
}

这是满足 Visual Studio 的实现
public Task<bool> Contains(string key)
{
    return Task.FromResult(false);
}

这个实现写起来很方便,而且似乎可以达到同样的目的:
public async Task<bool> Contains(string key)
{
    return false;
}

然而,Visual Studio 发出嘶嘶声并坚持:



我很乐意忽略该警告并避免使用 Task.FromResult(...)

使用后一个选项有什么负面影响吗?

最佳答案

出现“hissy fit”的原因是编译器需要做很多工作来呈现一个以所有预期正确方式工作的任务,你可以看到 by compiling and decompiling it
Task.FromResult 更干净,但可能仍然有开销 - IIRC 在某些情况下 Task.FromResult 可能在这里有效工作(每次返回相同的对象),但我不会依赖它。

有两种实用可靠的方法:

  • 每次
  • 返回一个重用的静态 Task<bool> 结果
  • 使用 ValueTask<bool> - 如果您经常同步返回,这在这里看起来很理想

  • IE。
    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);
    }
    

    注意:在这种情况下,其中的第二个可能是不可能的,因为您没有定义接口(interface)。但是:如果您设计的接口(interface)需要允许异步使用但实际上可能是同步的:请考虑使用 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;
    }
    

    关于c# - 没有 await 与 Task.FromResult 的异步方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52146203/

    10-11 09:16