gpt4 book ai didi

c# - 等待或 Task.FromResult

转载 作者:IT王子 更新时间:2023-10-29 04:49:28 34 4
gpt4 key购买 nike

我有一项服务可以说,

public interface ISomeService
{
Task<bool> DoSomeExpensiveCheckAsync(string parameter);
}

我有这个类来使用服务。它只需要做一些简单的空检查,然后返回服务响应。

public class SomeServiceConsumer
{
private readonly ISomeService _serviceClient;

public SomeServiceConsumer(ISomeService serviceClient)
{
_serviceClient = serviceClient;
}

public async Task<bool> DoSomething1Async(string someParameter)
{
if (string.IsNullOrWhiteSpace(someParameter))
{
return false;
}
return await _serviceClient.DoSomeExpensiveCheckAsync(someParameter);
}

//No async or await keywords
public Task<bool> DoSomething2Async(string someParameter)
{
if (string.IsNullOrWhiteSpace(someParameter))
{
return Task.FromResult(false);
}
return _serviceClient.DoSomeExpensiveCheckAsync(someParameter);
}
}

我应该执行 DoSomething1Async 还是 DoSomething2Async

根据 this answer ,我不应该用不必要的 await 包装,但随后我必须使用 Task.FromResult(false) 进行短路,如 DoSomething2Async

但根据this answer在使用 try/catchusing 语句的情况下,我实际上应该在返回之前 await

我这样说对吗

  1. 如果我必须使用 try/catchusing 那么我应该 await

  2. 否则,如果您只想返回,请不要await。并使用 Task.FromResult 进行短路

我更喜欢 DoSomething1Async,如果有人说这无关紧要,我想在任何地方都这样做:)。

最佳答案

如果你担心它,缓存Task:

static readonly Task<bool> falseTask = Task.FromResult(false);

async 关键字还在返回的 Task 中包装异常,以及适当的堆栈跟踪。这是性能的权衡,行为安全。

让我们看看不同的场景,每个场景都不一样:

async Task UseSomething1Async(string someParameter)
{
// if IsNullOrWhiteSpace throws an exception, it will be wrapped in
// the task and not thrown here.
Task t1 = DoSomething1Async(someParameter);

// rather, it'll get thrown here. this is best practice,
// it's what users of Task-returning methods expect.
await t1;

// if IsNullOrWhiteSpace throws an exception, it will
// be thrown here. users will not expect this.
Task t2 = DoSomething2Async(someParameter);

// this would never have been reached.
await t2;
}

这里只是说明一点——IsNullOrWhiteSpace 实际上并没有因为任何原因抛出任何异常。

就堆栈跟踪而言,异步堆栈跟踪由您等待的位置决定。没有 await 意味着该方法将从堆栈跟踪中消失。

DoSomeExpensiveCheckAsync 抛出异常。在 DoSomething1Async 的情况下,堆栈跟踪将类似于 caller -> DoSomething1Async -> DoSomeExpensiveCheckAsync

DoSomething2Async 的情况下,堆栈跟踪看起来像 caller -> DoSomeExpensiveCheckAsync。根据代码的复杂性,这可能会使调试变得困难。

在实践中,如果我知道在它之前不会抛出异常,并且方法名称只是一个重载转发到另一个重载,我通常只会直接返回一个Task。这条规则总有异常(exception),一定会有您想要最大化性能的地方。仔细挑选,意识到您可能会让您和您的用户的生活更加艰难。

关于c# - 等待或 Task.FromResult,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26898262/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com